Search in sources :

Example 46 with Face

use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.

the class EnvMapUtils method generatePrefilteredEnvMap.

/**
     * Generates the prefiltered env map (used for image based specular
     * lighting) With the GGX/Shlick brdf
     * {@link EnvMapUtils#getSphericalHarmonicsCoefficents(com.jme3.texture.TextureCubeMap)}
     * Note that the output cube map is in RGBA8 format.
     *
     * @param sourceEnvMap
     * @param targetMapSize the size of the irradiance map to generate
     * @param store
     * @param fixSeamsMethod the method to fix seams
     * @return The irradiance cube map for the given coefficients
     */
public static TextureCubeMap generatePrefilteredEnvMap(TextureCubeMap sourceEnvMap, int targetMapSize, FixSeamsMethod fixSeamsMethod, TextureCubeMap store) {
    TextureCubeMap pem = store;
    if (pem == null) {
        pem = new TextureCubeMap(targetMapSize, targetMapSize, Image.Format.RGB16F);
        pem.setMagFilter(Texture.MagFilter.Bilinear);
        pem.setMinFilter(Texture.MinFilter.Trilinear);
        pem.getImage().setColorSpace(ColorSpace.Linear);
    }
    int nbMipMap = (int) (Math.log(targetMapSize) / Math.log(2) - 1);
    CubeMapWrapper sourceWrapper = new CubeMapWrapper(sourceEnvMap);
    CubeMapWrapper targetWrapper = new CubeMapWrapper(pem);
    targetWrapper.initMipMaps(nbMipMap);
    Vector3f texelVect = new Vector3f();
    Vector3f color = new Vector3f();
    ColorRGBA outColor = new ColorRGBA();
    for (int mipLevel = 0; mipLevel < nbMipMap; mipLevel++) {
        System.err.println("mip level " + mipLevel);
        float roughness = getRoughnessFromMip(mipLevel, nbMipMap);
        int nbSamples = getSampleFromMip(mipLevel, nbMipMap);
        int targetMipMapSize = (int) pow(2, nbMipMap + 1 - mipLevel);
        for (int face = 0; face < 6; face++) {
            System.err.println("face " + face);
            for (int y = 0; y < targetMipMapSize; y++) {
                for (int x = 0; x < targetMipMapSize; x++) {
                    color.set(0, 0, 0);
                    getVectorFromCubemapFaceTexCoord(x, y, targetMipMapSize, face, texelVect, FixSeamsMethod.Wrap);
                    prefilterEnvMapTexel(sourceWrapper, roughness, texelVect, nbSamples, color);
                    outColor.set(color.x, color.y, color.z, 1.0f);
                    // System.err.println("coords " + x + "," + y);
                    targetWrapper.setPixel(x, y, face, mipLevel, outColor);
                }
            }
        }
    }
    return pem;
}
Also used : ColorRGBA(com.jme3.math.ColorRGBA) TextureCubeMap(com.jme3.texture.TextureCubeMap) Vector3f(com.jme3.math.Vector3f)

Example 47 with Face

use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.

the class EnvMapUtils method getSphericalHarmonicsCoefficents.

/**
     * Returns the Spherical Harmonics coefficients for this cube map.
     *
     * The method used is the one from this article :
     * http://graphics.stanford.edu/papers/envmap/envmap.pdf
     *
     * Also good resources on spherical harmonics
     * http://dickyjim.wordpress.com/2013/09/04/spherical-harmonics-for-beginners/
     *
     * @param cubeMap the environment cube map to compute SH for
     * @param fixSeamsMethod method to fix seams when computing the SH
     * coefficients
     * @return an array of 9 vector3f representing thos coefficients for each
     * r,g,b channnel
     */
public static Vector3f[] getSphericalHarmonicsCoefficents(TextureCubeMap cubeMap, FixSeamsMethod fixSeamsMethod) {
    Vector3f[] shCoef = new Vector3f[NUM_SH_COEFFICIENT];
    float[] shDir = new float[9];
    float weightAccum = 0.0f;
    float weight;
    if (cubeMap.getImage().getData(0) == null) {
        throw new IllegalStateException("The cube map must contain Efficient data, if you rendered the cube map on the GPU plase use renderer.readFrameBuffer, to create a CPU image");
    }
    int width = cubeMap.getImage().getWidth();
    int height = cubeMap.getImage().getHeight();
    Vector3f texelVect = new Vector3f();
    ColorRGBA color = new ColorRGBA();
    CubeMapWrapper envMapReader = new CubeMapWrapper(cubeMap);
    for (int face = 0; face < 6; face++) {
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                weight = getSolidAngleAndVector(x, y, width, face, texelVect, fixSeamsMethod);
                evalShBasis(texelVect, shDir);
                envMapReader.getPixel(x, y, face, color);
                for (int i = 0; i < NUM_SH_COEFFICIENT; i++) {
                    if (shCoef[i] == null) {
                        shCoef[i] = new Vector3f();
                    }
                    shCoef[i].setX(shCoef[i].x + color.r * shDir[i] * weight);
                    shCoef[i].setY(shCoef[i].y + color.g * shDir[i] * weight);
                    shCoef[i].setZ(shCoef[i].z + color.b * shDir[i] * weight);
                }
                weightAccum += weight;
            }
        }
    }
    /* Normalization - The sum of solid angle should be equal to the solid angle of the sphere (4 PI), so
         * normalize in order our weightAccum exactly match 4 PI. */
    for (int i = 0; i < NUM_SH_COEFFICIENT; ++i) {
        shCoef[i].multLocal(4.0f * PI / weightAccum);
    }
    return shCoef;
}
Also used : ColorRGBA(com.jme3.math.ColorRGBA) Vector3f(com.jme3.math.Vector3f)

Example 48 with Face

use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.

the class LightProbeFactory method generatePbrMaps.

/**
     * Internally called to generate the maps.
     * This method will spawn 7 thread (one for the IrradianceMap, and one for each face of the prefiltered env map).
     * Those threads will be executed in a ScheduledThreadPoolExecutor that will be shutdown when the genration is done.
     * 
     * @param envMap the raw env map rendered by the env camera
     * @param probe the LigthProbe to generate maps for
     * @param app the Application
     * @param listener a progress listener. (can be null if no progress reporting is needed)
     */
private static void generatePbrMaps(TextureCubeMap envMap, final LightProbe probe, Application app, final JobProgressListener<LightProbe> listener) {
    IrradianceMapGenerator irrMapGenerator;
    PrefilteredEnvMapFaceGenerator[] pemGenerators = new PrefilteredEnvMapFaceGenerator[6];
    final JobState jobState = new JobState(new ScheduledThreadPoolExecutor(7));
    irrMapGenerator = new IrradianceMapGenerator(app, new JobListener(listener, jobState, probe, 6));
    int size = envMap.getImage().getWidth();
    irrMapGenerator.setGenerationParam(EnvMapUtils.duplicateCubeMap(envMap), size, EnvMapUtils.FixSeamsMethod.Wrap, probe.getIrradianceMap());
    jobState.executor.execute(irrMapGenerator);
    for (int i = 0; i < pemGenerators.length; i++) {
        pemGenerators[i] = new PrefilteredEnvMapFaceGenerator(app, i, new JobListener(listener, jobState, probe, i));
        pemGenerators[i].setGenerationParam(EnvMapUtils.duplicateCubeMap(envMap), size, EnvMapUtils.FixSeamsMethod.Wrap, probe.getPrefilteredEnvMap());
        jobState.executor.execute(pemGenerators[i]);
    }
}
Also used : IrradianceMapGenerator(com.jme3.environment.generation.IrradianceMapGenerator) ScheduledThreadPoolExecutor(java.util.concurrent.ScheduledThreadPoolExecutor) PrefilteredEnvMapFaceGenerator(com.jme3.environment.generation.PrefilteredEnvMapFaceGenerator)

Example 49 with Face

use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.

the class IrradianceMapGenerator method generateIrradianceMap.

/**
     * Generates the Irradiance map (used for image based difuse lighting) from
     * Spherical Harmonics coefficients previously computed with
     * {@link EnvMapUtils#getSphericalHarmonicsCoefficents(com.jme3.texture.TextureCubeMap)}
     *
     * @param shCoeffs the SH coeffs
     * @param targetMapSize the size of the irradiance map to generate
     * @param fixSeamsMethod the method to fix seams
     * @param store
     * @return The irradiance cube map for the given coefficients
     */
public TextureCubeMap generateIrradianceMap(Vector3f[] shCoeffs, int targetMapSize, EnvMapUtils.FixSeamsMethod fixSeamsMethod, TextureCubeMap store) {
    TextureCubeMap irrCubeMap = store;
    setEnd(6 + 6);
    for (int i = 0; i < 6; i++) {
        ByteBuffer buf = BufferUtils.createByteBuffer(targetMapSize * targetMapSize * store.getImage().getFormat().getBitsPerPixel() / 8);
        irrCubeMap.getImage().setData(i, buf);
        progress();
    }
    Vector3f texelVect = new Vector3f();
    ColorRGBA color = new ColorRGBA(ColorRGBA.Black);
    float[] shDir = new float[9];
    CubeMapWrapper envMapWriter = new CubeMapWrapper(irrCubeMap);
    for (int face = 0; face < 6; face++) {
        for (int y = 0; y < targetMapSize; y++) {
            for (int x = 0; x < targetMapSize; x++) {
                EnvMapUtils.getVectorFromCubemapFaceTexCoord(x, y, targetMapSize, face, texelVect, fixSeamsMethod);
                EnvMapUtils.evalShBasis(texelVect, shDir);
                color.set(0, 0, 0, 0);
                for (int i = 0; i < EnvMapUtils.NUM_SH_COEFFICIENT; i++) {
                    color.set(color.r + shCoeffs[i].x * shDir[i] * shBandFactor[i], color.g + shCoeffs[i].y * shDir[i] * shBandFactor[i], color.b + shCoeffs[i].z * shDir[i] * shBandFactor[i], 1.0f);
                }
                //clamping the color because very low value close to zero produce artifacts
                color.r = Math.max(0.0001f, color.r);
                color.g = Math.max(0.0001f, color.g);
                color.b = Math.max(0.0001f, color.b);
                envMapWriter.setPixel(x, y, face, color);
            }
        }
        progress();
    }
    return irrCubeMap;
}
Also used : ColorRGBA(com.jme3.math.ColorRGBA) TextureCubeMap(com.jme3.texture.TextureCubeMap) Vector3f(com.jme3.math.Vector3f) CubeMapWrapper(com.jme3.environment.util.CubeMapWrapper) ByteBuffer(java.nio.ByteBuffer)

Example 50 with Face

use of com.jme3.scene.plugins.blender.meshes.Face in project jmonkeyengine by jMonkeyEngine.

the class PrefilteredEnvMapFaceGenerator method generatePrefilteredEnvMap.

/**
     * Generates the prefiltered env map (used for image based specular
     * lighting) With the GGX/Shlick brdf
     * {@link EnvMapUtils#getSphericalHarmonicsCoefficents(com.jme3.texture.TextureCubeMap)}
     * Note that the output cube map is in RGBA8 format.
     *
     * @param sourceEnvMap
     * @param targetMapSize the size of the irradiance map to generate
     * @param store
     * @param fixSeamsMethod the method to fix seams
     * @return The irradiance cube map for the given coefficients
     */
private TextureCubeMap generatePrefilteredEnvMap(TextureCubeMap sourceEnvMap, int targetMapSize, EnvMapUtils.FixSeamsMethod fixSeamsMethod, TextureCubeMap store) {
    TextureCubeMap pem = store;
    int nbMipMap = (int) (Math.log(targetMapSize) / Math.log(2) - 1);
    setEnd(nbMipMap);
    CubeMapWrapper sourceWrapper = new CubeMapWrapper(sourceEnvMap);
    CubeMapWrapper targetWrapper = new CubeMapWrapper(pem);
    Vector3f texelVect = new Vector3f();
    Vector3f color = new Vector3f();
    ColorRGBA outColor = new ColorRGBA();
    for (int mipLevel = 0; mipLevel < nbMipMap; mipLevel++) {
        float roughness = getRoughnessFromMip(mipLevel, nbMipMap);
        int nbSamples = getSampleFromMip(mipLevel, nbMipMap);
        int targetMipMapSize = (int) pow(2, nbMipMap + 1 - mipLevel);
        for (int y = 0; y < targetMipMapSize; y++) {
            for (int x = 0; x < targetMipMapSize; x++) {
                color.set(0, 0, 0);
                getVectorFromCubemapFaceTexCoord(x, y, targetMipMapSize, face, texelVect, EnvMapUtils.FixSeamsMethod.Wrap);
                prefilterEnvMapTexel(sourceWrapper, roughness, texelVect, nbSamples, color);
                outColor.set(Math.max(color.x, 0.0001f), Math.max(color.y, 0.0001f), Math.max(color.z, 0.0001f), 1);
                log.log(Level.FINE, "coords {0},{1}", new Object[] { x, y });
                targetWrapper.setPixel(x, y, face, mipLevel, outColor);
            }
        }
        progress();
    }
    return pem;
}
Also used : ColorRGBA(com.jme3.math.ColorRGBA) TextureCubeMap(com.jme3.texture.TextureCubeMap) Vector3f(com.jme3.math.Vector3f) CubeMapWrapper(com.jme3.environment.util.CubeMapWrapper) EnvMapUtils.getHammersleyPoint(com.jme3.environment.util.EnvMapUtils.getHammersleyPoint)

Aggregations

Vector3f (com.jme3.math.Vector3f)26 ArrayList (java.util.ArrayList)19 List (java.util.List)13 ColorRGBA (com.jme3.math.ColorRGBA)10 FloatBuffer (java.nio.FloatBuffer)9 Vector2f (com.jme3.math.Vector2f)8 Face (com.jme3.scene.plugins.blender.meshes.Face)8 HashMap (java.util.HashMap)8 HashSet (java.util.HashSet)8 VertexBuffer (com.jme3.scene.VertexBuffer)7 Structure (com.jme3.scene.plugins.blender.file.Structure)6 Material (com.jme3.material.Material)5 Node (com.jme3.scene.Node)5 IndexBuffer (com.jme3.scene.mesh.IndexBuffer)5 Pointer (com.jme3.scene.plugins.blender.file.Pointer)5 Edge (com.jme3.scene.plugins.blender.meshes.Edge)5 Line (org.twak.utils.Line)5 Geometry (com.jme3.scene.Geometry)4 TextureCubeMap (com.jme3.texture.TextureCubeMap)4 File (java.io.File)4