Search in sources :

Example 6 with LightProbe

use of com.jme3.light.LightProbe in project jmonkeyengine by jMonkeyEngine.

the class SinglePassAndImageBasedLightingLogic method updateLightListUniforms.

/**
     * Uploads the lights in the light list as two uniform arrays.<br/><br/> *
     * <p>
     * <code>uniform vec4 g_LightColor[numLights];</code><br/> //
     * g_LightColor.rgb is the diffuse/specular color of the light.<br/> //
     * g_Lightcolor.a is the type of light, 0 = Directional, 1 = Point, <br/> //
     * 2 = Spot. <br/> <br/>
     * <code>uniform vec4 g_LightPosition[numLights];</code><br/> //
     * g_LightPosition.xyz is the position of the light (for point lights)<br/>
     * // or the direction of the light (for directional lights).<br/> //
     * g_LightPosition.w is the inverse radius (1/r) of the light (for
     * attenuation) <br/> </p>
     */
protected int updateLightListUniforms(Shader shader, Geometry g, LightList lightList, int numLights, RenderManager rm, int startIndex, int lastTexUnit) {
    if (numLights == 0) {
        // this shader does not do lighting, ignore.
        return 0;
    }
    Uniform lightData = shader.getUniform("g_LightData");
    //8 lights * max 3
    lightData.setVector4Length(numLights * 3);
    Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
    Uniform lightProbeData = shader.getUniform("g_LightProbeData");
    lightProbeData.setVector4Length(1);
    Uniform lightProbeIrrMap = shader.getUniform("g_IrradianceMap");
    Uniform lightProbePemMap = shader.getUniform("g_PrefEnvMap");
    lightProbe = null;
    if (startIndex != 0) {
        // apply additive blending for 2nd and future passes
        rm.getRenderer().applyRenderState(ADDITIVE_LIGHT);
        ambientColor.setValue(VarType.Vector4, ColorRGBA.Black);
    } else {
        lightProbe = extractIndirectLights(lightList, true);
        ambientColor.setValue(VarType.Vector4, ambientLightColor);
    }
    //If there is a lightProbe in the list we force it's render on the first pass
    if (lightProbe != null) {
        BoundingSphere s = (BoundingSphere) lightProbe.getBounds();
        lightProbeData.setVector4InArray(lightProbe.getPosition().x, lightProbe.getPosition().y, lightProbe.getPosition().z, 1f / s.getRadius(), 0);
        //assigning new texture indexes
        int irrUnit = lastTexUnit++;
        int pemUnit = lastTexUnit++;
        rm.getRenderer().setTexture(irrUnit, lightProbe.getIrradianceMap());
        lightProbeIrrMap.setValue(VarType.Int, irrUnit);
        rm.getRenderer().setTexture(pemUnit, lightProbe.getPrefilteredEnvMap());
        lightProbePemMap.setValue(VarType.Int, pemUnit);
    } else {
        //Disable IBL for this pass
        lightProbeData.setVector4InArray(0, 0, 0, -1, 0);
    }
    int lightDataIndex = 0;
    TempVars vars = TempVars.get();
    Vector4f tmpVec = vars.vect4f1;
    int curIndex;
    int endIndex = numLights + startIndex;
    for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) {
        Light l = lightList.get(curIndex);
        if (l.getType() == Light.Type.Ambient) {
            endIndex++;
            continue;
        }
        ColorRGBA color = l.getColor();
        if (l.getType() != Light.Type.Probe) {
            lightData.setVector4InArray(color.getRed(), color.getGreen(), color.getBlue(), l.getType().getId(), lightDataIndex);
            lightDataIndex++;
        }
        switch(l.getType()) {
            case Directional:
                DirectionalLight dl = (DirectionalLight) l;
                Vector3f dir = dl.getDirection();
                //Data directly sent in view space to avoid a matrix mult for each pixel
                tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex);
                lightDataIndex++;
                //PADDING
                lightData.setVector4InArray(0, 0, 0, 0, lightDataIndex);
                lightDataIndex++;
                break;
            case Point:
                PointLight pl = (PointLight) l;
                Vector3f pos = pl.getPosition();
                float invRadius = pl.getInvRadius();
                tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex);
                lightDataIndex++;
                //PADDING
                lightData.setVector4InArray(0, 0, 0, 0, lightDataIndex);
                lightDataIndex++;
                break;
            case Spot:
                SpotLight sl = (SpotLight) l;
                Vector3f pos2 = sl.getPosition();
                Vector3f dir2 = sl.getDirection();
                float invRange = sl.getInvSpotRange();
                float spotAngleCos = sl.getPackedAngleCos();
                tmpVec.set(pos2.getX(), pos2.getY(), pos2.getZ(), 1.0f);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRange, lightDataIndex);
                lightDataIndex++;
                tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0.0f);
                lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex);
                lightDataIndex++;
                break;
            default:
                throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
        }
    }
    vars.release();
    //Padding of unsued buffer space
    while (lightDataIndex < numLights * 3) {
        lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex);
        lightDataIndex++;
    }
    return curIndex;
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) TempVars(com.jme3.util.TempVars)

Example 7 with LightProbe

use of com.jme3.light.LightProbe in project jmonkeyengine by jMonkeyEngine.

the class LightsDebugState method cleanProbes.

private void cleanProbes() {
    if (probes.size() != probeMapping.size()) {
        for (LightProbe probe : probeMapping.keySet()) {
            if (!probes.contains(probe)) {
                garbage.add(probe);
            }
        }
        for (LightProbe probe : garbage) {
            probeMapping.remove(probe);
        }
        garbage.clear();
        probes.clear();
    }
}
Also used : LightProbe(com.jme3.light.LightProbe)

Example 8 with LightProbe

use of com.jme3.light.LightProbe 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)

Example 9 with LightProbe

use of com.jme3.light.LightProbe 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 10 with LightProbe

use of com.jme3.light.LightProbe in project jmonkeyengine by jMonkeyEngine.

the class LightProbeBlendingProcessor method computeBlendFactors.

private float computeBlendFactors(List<BlendFactor> blendFactors) {
    float sumBlendFactors = 0;
    for (Spatial scene : viewPort.getScenes()) {
        for (Light light : scene.getWorldLightList()) {
            if (light.getType() == Light.Type.Probe) {
                LightProbe p = (LightProbe) light;
                TempVars vars = TempVars.get();
                boolean intersect = p.intersectsFrustum(viewPort.getCamera(), vars);
                vars.release();
                //check if the probe is inside the camera frustum
                if (intersect) {
                    //is the poi inside the bounds of this probe
                    if (poi.getWorldBound().intersects(p.getBounds())) {
                        //computing the distance as we need it to check if th epoi in in the inner radius and later to compute the weight
                        float outerRadius = ((BoundingSphere) p.getBounds()).getRadius();
                        float innerRadius = outerRadius * 0.5f;
                        float distance = p.getBounds().getCenter().distance(poi.getWorldTranslation());
                        // if the poi in inside the inner range of this probe, then this probe is the only one that matters.
                        if (distance < innerRadius) {
                            blendFactors.clear();
                            blendFactors.add(new BlendFactor(p, 1.0f));
                            return 1.0f;
                        }
                        //else we need to compute the weight of this probe and collect it for blending
                        float ndf = (distance - innerRadius) / (outerRadius - innerRadius);
                        sumBlendFactors += ndf;
                        blendFactors.add(new BlendFactor(p, ndf));
                    }
                }
            }
        }
    }
    return sumBlendFactors;
}
Also used : BoundingSphere(com.jme3.bounding.BoundingSphere) Spatial(com.jme3.scene.Spatial) TempVars(com.jme3.util.TempVars)

Aggregations

BoundingSphere (com.jme3.bounding.BoundingSphere)6 LightProbe (com.jme3.light.LightProbe)6 EnvironmentCamera (com.jme3.environment.EnvironmentCamera)3 TempVars (com.jme3.util.TempVars)3 Node (com.jme3.scene.Node)2 BoundingBox (com.jme3.bounding.BoundingBox)1 BoundingVolume (com.jme3.bounding.BoundingVolume)1 IrradianceMapGenerator (com.jme3.environment.generation.IrradianceMapGenerator)1 PrefilteredEnvMapFaceGenerator (com.jme3.environment.generation.PrefilteredEnvMapFaceGenerator)1 Light (com.jme3.light.Light)1 Material (com.jme3.material.Material)1 Geometry (com.jme3.scene.Geometry)1 Spatial (com.jme3.scene.Spatial)1 TextureCubeMap (com.jme3.texture.TextureCubeMap)1 ScheduledThreadPoolExecutor (java.util.concurrent.ScheduledThreadPoolExecutor)1