Search in sources :

Example 16 with TextureCubeMap

use of com.jme3.texture.TextureCubeMap 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 17 with TextureCubeMap

use of com.jme3.texture.TextureCubeMap in project jmonkeyengine by jMonkeyEngine.

the class EnvMapUtils method getCubeMapCrossDebugViewWithMipMaps.

public static Node getCubeMapCrossDebugViewWithMipMaps(TextureCubeMap cubeMap, AssetManager assetManager) {
    Node n = new Node("CubeMapDebug" + cubeMap.getName());
    int size = cubeMap.getImage().getWidth();
    int nbMips = cubeMap.getImage().getMipMapSizes().length;
    Picture[] pics = new Picture[6 * nbMips];
    // 128f / (float) size;
    float ratio = 1f;
    int offset = 0;
    int guiOffset = 0;
    for (int mipLevel = 0; mipLevel < nbMips; mipLevel++) {
        size = Math.max(1, cubeMap.getImage().getWidth() >> mipLevel);
        int dataSize = cubeMap.getImage().getMipMapSizes()[mipLevel];
        byte[] dataArray = new byte[dataSize];
        for (int i = 0; i < 6; i++) {
            ByteBuffer bb = cubeMap.getImage().getData(i);
            bb.rewind();
            bb.position(offset);
            bb.get(dataArray, 0, dataSize);
            ByteBuffer data = BufferUtils.createByteBuffer(dataArray);
            pics[i] = new Picture("bla");
            Texture2D tex = new Texture2D(new Image(cubeMap.getImage().getFormat(), size, size, data, cubeMap.getImage().getColorSpace()));
            pics[i].setTexture(assetManager, tex, true);
            pics[i].setWidth(size);
            pics[i].setHeight(size);
            n.attachChild(pics[i]);
        }
        pics[0].setLocalTranslation(guiOffset + size, guiOffset + size * 2, 1);
        pics[0].setLocalRotation(new Quaternion().fromAngleAxis(PI, Vector3f.UNIT_Z));
        pics[1].setLocalTranslation(guiOffset + size * 3, guiOffset + size * 2, 1);
        pics[1].setLocalRotation(new Quaternion().fromAngleAxis(PI, Vector3f.UNIT_Z));
        pics[2].setLocalTranslation(guiOffset + size * 2, guiOffset + size * 3, 1);
        pics[2].setLocalRotation(new Quaternion().fromAngleAxis(PI, Vector3f.UNIT_Z));
        pics[3].setLocalTranslation(guiOffset + size * 2, guiOffset + size, 1);
        pics[3].setLocalRotation(new Quaternion().fromAngleAxis(PI, Vector3f.UNIT_Z));
        pics[4].setLocalTranslation(guiOffset + size * 2, guiOffset + size * 2, 1);
        pics[4].setLocalRotation(new Quaternion().fromAngleAxis(PI, Vector3f.UNIT_Z));
        pics[5].setLocalTranslation(guiOffset + size * 4, guiOffset + size * 2, 1);
        pics[5].setLocalRotation(new Quaternion().fromAngleAxis(PI, Vector3f.UNIT_Z));
        guiOffset += size * 2 + 1;
        offset += dataSize;
    }
    Quad q = new Quad(cubeMap.getImage().getWidth() * 4 + nbMips, guiOffset + size);
    Geometry g = new Geometry("bg", q);
    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setColor("Color", ColorRGBA.Black);
    g.setMaterial(mat);
    g.setLocalTranslation(0, 0, 0);
    n.attachChild(g);
    n.setLocalScale(ratio);
    return n;
}
Also used : Quad(com.jme3.scene.shape.Quad) Texture2D(com.jme3.texture.Texture2D) Quaternion(com.jme3.math.Quaternion) Node(com.jme3.scene.Node) Material(com.jme3.material.Material) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer) Geometry(com.jme3.scene.Geometry) Picture(com.jme3.ui.Picture)

Example 18 with TextureCubeMap

use of com.jme3.texture.TextureCubeMap in project jmonkeyengine by jMonkeyEngine.

the class EnvMapUtils method makeCubeMap.

/**
     * Creates a cube map from 6 images
     *
     * @param leftImg the west side image, also called negative x (negX) or left
     * image
     * @param rightImg the east side image, also called positive x (posX) or
     * right image
     * @param downImg the bottom side image, also called negative y (negY) or
     * down image
     * @param upImg the up side image, also called positive y (posY) or up image
     * @param backImg the south side image, also called positive z (posZ) or
     * back image
     * @param frontImg the north side image, also called negative z (negZ) or
     * front image
     * @param format the format of the image
     * @return a cube map
     */
public static TextureCubeMap makeCubeMap(Image rightImg, Image leftImg, Image upImg, Image downImg, Image backImg, Image frontImg, Image.Format format) {
    Image cubeImage = new Image(format, leftImg.getWidth(), leftImg.getHeight(), null, ColorSpace.Linear);
    cubeImage.addData(rightImg.getData(0));
    cubeImage.addData(leftImg.getData(0));
    cubeImage.addData(upImg.getData(0));
    cubeImage.addData(downImg.getData(0));
    cubeImage.addData(backImg.getData(0));
    cubeImage.addData(frontImg.getData(0));
    if (leftImg.getEfficentData() != null) {
        // also consilidate efficient data
        ArrayList<Object> efficientData = new ArrayList<Object>(6);
        efficientData.add(rightImg.getEfficentData());
        efficientData.add(leftImg.getEfficentData());
        efficientData.add(upImg.getEfficentData());
        efficientData.add(downImg.getEfficentData());
        efficientData.add(backImg.getEfficentData());
        efficientData.add(frontImg.getEfficentData());
        cubeImage.setEfficentData(efficientData);
    }
    TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
    cubeMap.setAnisotropicFilter(0);
    cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
    cubeMap.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
    cubeMap.setWrap(Texture.WrapMode.EdgeClamp);
    return cubeMap;
}
Also used : TextureCubeMap(com.jme3.texture.TextureCubeMap) ArrayList(java.util.ArrayList) Image(com.jme3.texture.Image)

Example 19 with TextureCubeMap

use of com.jme3.texture.TextureCubeMap 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 20 with TextureCubeMap

use of com.jme3.texture.TextureCubeMap in project jmonkeyengine by jMonkeyEngine.

the class LightProbeFactory method makeProbe.

/**
     * Creates a LightProbe with the giver EnvironmentCamera in the given scene.
     * 
     * Note that this is an assynchronous process that will run on multiple threads.
     * The process is thread safe.
     * The created lightProbe will only be marked as ready when the rendering process is done.
     *      
     * The JobProgressListener will be notified of the progress of the generation. 
     * Note that you can also use a {@link JobProgressAdapter}. 
     * 
     * @see LightProbe
     * @see EnvironmentCamera
     * @see JobProgressListener
     
     * @param envCam the EnvironmentCamera
     * @param scene the Scene
     * @param listener the listener of the genration progress.
     * @return the created LightProbe
     */
public static LightProbe makeProbe(final EnvironmentCamera envCam, Spatial scene, final JobProgressListener<LightProbe> listener) {
    final LightProbe probe = new LightProbe();
    probe.setPosition(envCam.getPosition());
    probe.setIrradianceMap(EnvMapUtils.createIrradianceMap(envCam.getSize(), envCam.getImageFormat()));
    probe.setPrefilteredMap(EnvMapUtils.createPrefilteredEnvMap(envCam.getSize(), envCam.getImageFormat()));
    envCam.snapshot(scene, new JobProgressAdapter<TextureCubeMap>() {

        @Override
        public void done(TextureCubeMap map) {
            generatePbrMaps(map, probe, envCam.getApplication(), listener);
        }
    });
    return probe;
}
Also used : LightProbe(com.jme3.light.LightProbe) TextureCubeMap(com.jme3.texture.TextureCubeMap)

Aggregations

TextureCubeMap (com.jme3.texture.TextureCubeMap)16 Image (com.jme3.texture.Image)10 ColorRGBA (com.jme3.math.ColorRGBA)6 Vector3f (com.jme3.math.Vector3f)6 ByteBuffer (java.nio.ByteBuffer)6 Material (com.jme3.material.Material)4 Geometry (com.jme3.scene.Geometry)4 Texture2D (com.jme3.texture.Texture2D)4 ArrayList (java.util.ArrayList)4 PixelInputOutput (com.jme3.scene.plugins.blender.textures.io.PixelInputOutput)3 TextureKey (com.jme3.asset.TextureKey)2 BoundingSphere (com.jme3.bounding.BoundingSphere)2 CubeMapWrapper (com.jme3.environment.util.CubeMapWrapper)2 Quaternion (com.jme3.math.Quaternion)2 Node (com.jme3.scene.Node)2 Quad (com.jme3.scene.shape.Quad)2 Texture (com.jme3.texture.Texture)2 Picture (com.jme3.ui.Picture)2 IrradianceMapGenerator (com.jme3.environment.generation.IrradianceMapGenerator)1 PrefilteredEnvMapFaceGenerator (com.jme3.environment.generation.PrefilteredEnvMapFaceGenerator)1