Search in sources :

Example 36 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 37 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 38 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 39 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 40 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)24 ArrayList (java.util.ArrayList)13 ColorRGBA (com.jme3.math.ColorRGBA)8 Face (com.jme3.scene.plugins.blender.meshes.Face)8 List (java.util.List)8 FloatBuffer (java.nio.FloatBuffer)7 Vector2f (com.jme3.math.Vector2f)6 Structure (com.jme3.scene.plugins.blender.file.Structure)6 VertexBuffer (com.jme3.scene.VertexBuffer)5 Pointer (com.jme3.scene.plugins.blender.file.Pointer)5 Edge (com.jme3.scene.plugins.blender.meshes.Edge)5 TextureCubeMap (com.jme3.texture.TextureCubeMap)5 BlenderFileException (com.jme3.scene.plugins.blender.file.BlenderFileException)4 ByteBuffer (java.nio.ByteBuffer)4 IndexBuffer (com.jme3.scene.mesh.IndexBuffer)3 DynamicArray (com.jme3.scene.plugins.blender.file.DynamicArray)3 Image (com.jme3.texture.Image)3 IOException (java.io.IOException)3 HashMap (java.util.HashMap)3 CubeMapWrapper (com.jme3.environment.util.CubeMapWrapper)2