Search in sources :

Example 21 with Camera

use of com.jme3.renderer.Camera in project jmonkeyengine by jMonkeyEngine.

the class PssmShadowRenderer method postQueue.

@SuppressWarnings("fallthrough")
public void postQueue(RenderQueue rq) {
    for (Spatial scene : viewPort.getScenes()) {
        ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), ShadowMode.Receive, lightReceivers);
    }
    Camera viewCam = viewPort.getCamera();
    float zFar = zFarOverride;
    if (zFar == 0) {
        zFar = viewCam.getFrustumFar();
    }
    //We prevent computing the frustum points and splits with zeroed or negative near clip value
    float frustumNear = Math.max(viewCam.getFrustumNear(), 0.001f);
    ShadowUtil.updateFrustumPoints(viewCam, frustumNear, zFar, 1.0f, points);
    //shadowCam.setDirection(direction);
    shadowCam.getRotation().lookAt(direction, shadowCam.getUp());
    shadowCam.update();
    shadowCam.updateViewProjection();
    PssmShadowUtil.updateFrustumSplits(splitsArray, frustumNear, zFar, lambda);
    switch(splitsArray.length) {
        case 5:
            splits.a = splitsArray[4];
        case 4:
            splits.b = splitsArray[3];
        case 3:
            splits.g = splitsArray[2];
        case 2:
        case 1:
            splits.r = splitsArray[1];
            break;
    }
    Renderer r = renderManager.getRenderer();
    renderManager.setForcedMaterial(preshadowMat);
    renderManager.setForcedTechnique("PreShadow");
    for (int i = 0; i < nbSplits; i++) {
        // update frustum points based on current camera and split
        ShadowUtil.updateFrustumPoints(viewCam, splitsArray[i], splitsArray[i + 1], 1.0f, points);
        //Updating shadow cam with curent split frustra
        ShadowUtil.updateShadowCamera(viewPort, lightReceivers, shadowCam, points, splitOccluders, shadowMapSize);
        //saving light view projection matrix for this split            
        lightViewProjectionsMatrices[i].set(shadowCam.getViewProjectionMatrix());
        renderManager.setCamera(shadowCam, false);
        if (debugfrustums) {
            //                    frustrumFromBound(b.casterBB,ColorRGBA.Blue );
            //                    frustrumFromBound(b.receiverBB,ColorRGBA.Green );
            //                    frustrumFromBound(b.splitBB,ColorRGBA.Yellow );
            ((Node) viewPort.getScenes().get(0)).attachChild(createFrustum(points, i));
            ShadowUtil.updateFrustumPoints2(shadowCam, points);
            ((Node) viewPort.getScenes().get(0)).attachChild(createFrustum(points, i));
        }
        r.setFrameBuffer(shadowFB[i]);
        r.clearBuffers(true, true, true);
        // render shadow casters to shadow map
        viewPort.getQueue().renderShadowQueue(splitOccluders, renderManager, shadowCam, true);
    }
    debugfrustums = false;
    //restore setting for future rendering
    r.setFrameBuffer(viewPort.getOutputFrameBuffer());
    renderManager.setForcedMaterial(null);
    renderManager.setForcedTechnique(null);
    renderManager.setCamera(viewCam, false);
}
Also used : Spatial(com.jme3.scene.Spatial) Node(com.jme3.scene.Node) Renderer(com.jme3.renderer.Renderer) Camera(com.jme3.renderer.Camera)

Example 22 with Camera

use of com.jme3.renderer.Camera in project jmonkeyengine by jMonkeyEngine.

the class ShadowUtil method getGeometriesInCamFrustum.

/**
     * Populates the outputGeometryList with the geometry of the
     * inputGeomtryList that are in the frustum of the given camera
     *
     * @param inputGeometryList The list containing all geometry to check
     * against the camera frustum
     * @param camera the camera to check geometries against
     * @param outputGeometryList the list of all geometries that are in the
     * camera frustum
     */
public static void getGeometriesInCamFrustum(GeometryList inputGeometryList, Camera camera, GeometryList outputGeometryList) {
    for (int i = 0; i < inputGeometryList.size(); i++) {
        Geometry g = inputGeometryList.get(i);
        int planeState = camera.getPlaneState();
        camera.setPlaneState(0);
        if (camera.contains(g.getWorldBound()) != Camera.FrustumIntersect.Outside) {
            outputGeometryList.add(g);
        }
        camera.setPlaneState(planeState);
    }
}
Also used : Geometry(com.jme3.scene.Geometry)

Example 23 with Camera

use of com.jme3.renderer.Camera in project jmonkeyengine by jMonkeyEngine.

the class ShadowUtil method addGeometriesInCamFrustumAndViewPortFromNode.

/**
     * Helper function to recursively collect the geometries for getLitGeometriesInViewPort function.
     * 
     * @param vpCamera the viewPort camera 
     * @param cameras the camera array to check geometries against, representing the light viewspace
     * @param scene the Node to traverse or geometry to possibly add
     * @param outputGeometryList the output list of all geometries that are in the camera frustum
     */
private static void addGeometriesInCamFrustumAndViewPortFromNode(Camera vpCamera, Camera[] cameras, Spatial scene, RenderQueue.ShadowMode mode, GeometryList outputGeometryList) {
    if (scene.getCullHint() == Spatial.CullHint.Always)
        return;
    boolean inFrustum = false;
    for (int j = 0; j < cameras.length && inFrustum == false; j++) {
        Camera camera = cameras[j];
        int planeState = camera.getPlaneState();
        camera.setPlaneState(0);
        inFrustum = camera.contains(scene.getWorldBound()) != Camera.FrustumIntersect.Outside && scene.checkCulling(vpCamera);
        camera.setPlaneState(planeState);
    }
    if (inFrustum) {
        if (scene instanceof Node) {
            Node node = (Node) scene;
            for (Spatial child : node.getChildren()) {
                addGeometriesInCamFrustumAndViewPortFromNode(vpCamera, cameras, child, mode, outputGeometryList);
            }
        } else if (scene instanceof Geometry) {
            if (checkShadowMode(scene.getShadowMode(), mode) && !((Geometry) scene).isGrouped()) {
                outputGeometryList.add((Geometry) scene);
            }
        }
    }
}
Also used : Geometry(com.jme3.scene.Geometry) Spatial(com.jme3.scene.Spatial) Node(com.jme3.scene.Node) Camera(com.jme3.renderer.Camera)

Example 24 with Camera

use of com.jme3.renderer.Camera in project jmonkeyengine by jMonkeyEngine.

the class ShadowUtil method updateShadowCamera.

/**
     * Updates the shadow camera to properly contain the given points (which
     * contain the eye camera frustum corners) and the shadow occluder objects
     * collected through the traverse of the scene hierarchy
     */
public static void updateShadowCamera(ViewPort viewPort, GeometryList receivers, Camera shadowCam, Vector3f[] points, GeometryList splitOccluders, float shadowMapSize) {
    boolean ortho = shadowCam.isParallelProjection();
    shadowCam.setProjectionMatrix(null);
    if (ortho) {
        shadowCam.setFrustum(-shadowCam.getFrustumFar(), shadowCam.getFrustumFar(), -1, 1, 1, -1);
    }
    // create transform to rotate points to viewspace        
    Matrix4f viewProjMatrix = shadowCam.getViewProjectionMatrix();
    BoundingBox splitBB = computeBoundForPoints(points, viewProjMatrix);
    TempVars vars = TempVars.get();
    BoundingBox casterBB = new BoundingBox();
    BoundingBox receiverBB = new BoundingBox();
    int casterCount = 0, receiverCount = 0;
    for (int i = 0; i < receivers.size(); i++) {
        // convert bounding box to light's viewproj space
        Geometry receiver = receivers.get(i);
        BoundingVolume bv = receiver.getWorldBound();
        BoundingVolume recvBox = bv.transform(viewProjMatrix, vars.bbox);
        if (splitBB.intersects(recvBox)) {
            //Nehon : prevent NaN and infinity values to screw the final bounding box
            if (!Float.isNaN(recvBox.getCenter().x) && !Float.isInfinite(recvBox.getCenter().x)) {
                receiverBB.mergeLocal(recvBox);
                receiverCount++;
            }
        }
    }
    // collect splitOccluders through scene recursive traverse
    OccludersExtractor occExt = new OccludersExtractor(viewProjMatrix, casterCount, splitBB, casterBB, splitOccluders, vars);
    for (Spatial scene : viewPort.getScenes()) {
        occExt.addOccluders(scene);
    }
    casterCount = occExt.casterCount;
    //Nehon 08/18/2010 this is to avoid shadow bleeding when the ground is set to only receive shadows
    if (casterCount != receiverCount) {
        casterBB.setXExtent(casterBB.getXExtent() + 2.0f);
        casterBB.setYExtent(casterBB.getYExtent() + 2.0f);
        casterBB.setZExtent(casterBB.getZExtent() + 2.0f);
    }
    Vector3f casterMin = casterBB.getMin(vars.vect1);
    Vector3f casterMax = casterBB.getMax(vars.vect2);
    Vector3f receiverMin = receiverBB.getMin(vars.vect3);
    Vector3f receiverMax = receiverBB.getMax(vars.vect4);
    Vector3f splitMin = splitBB.getMin(vars.vect5);
    Vector3f splitMax = splitBB.getMax(vars.vect6);
    splitMin.z = 0;
    //        if (!ortho) {
    //            shadowCam.setFrustumPerspective(45, 1, 1, splitMax.z);
    //        }
    Matrix4f projMatrix = shadowCam.getProjectionMatrix();
    Vector3f cropMin = vars.vect7;
    Vector3f cropMax = vars.vect8;
    // IMPORTANT: Special handling for Z values
    cropMin.x = max(max(casterMin.x, receiverMin.x), splitMin.x);
    cropMax.x = min(min(casterMax.x, receiverMax.x), splitMax.x);
    cropMin.y = max(max(casterMin.y, receiverMin.y), splitMin.y);
    cropMax.y = min(min(casterMax.y, receiverMax.y), splitMax.y);
    cropMin.z = min(casterMin.z, splitMin.z);
    cropMax.z = min(receiverMax.z, splitMax.z);
    // Create the crop matrix.
    float scaleX, scaleY, scaleZ;
    float offsetX, offsetY, offsetZ;
    scaleX = (2.0f) / (cropMax.x - cropMin.x);
    scaleY = (2.0f) / (cropMax.y - cropMin.y);
    //Shadow map stabilization approximation from shaderX 7
    //from Practical Cascaded Shadow maps adapted to PSSM
    //scale stabilization
    float halfTextureSize = shadowMapSize * 0.5f;
    if (halfTextureSize != 0 && scaleX > 0 && scaleY > 0) {
        float scaleQuantizer = 0.1f;
        scaleX = 1.0f / FastMath.ceil(1.0f / scaleX * scaleQuantizer) * scaleQuantizer;
        scaleY = 1.0f / FastMath.ceil(1.0f / scaleY * scaleQuantizer) * scaleQuantizer;
    }
    offsetX = -0.5f * (cropMax.x + cropMin.x) * scaleX;
    offsetY = -0.5f * (cropMax.y + cropMin.y) * scaleY;
    //offset stabilization
    if (halfTextureSize != 0 && scaleX > 0 && scaleY > 0) {
        offsetX = FastMath.ceil(offsetX * halfTextureSize) / halfTextureSize;
        offsetY = FastMath.ceil(offsetY * halfTextureSize) / halfTextureSize;
    }
    scaleZ = 1.0f / (cropMax.z - cropMin.z);
    offsetZ = -cropMin.z * scaleZ;
    Matrix4f cropMatrix = vars.tempMat4;
    cropMatrix.set(scaleX, 0f, 0f, offsetX, 0f, scaleY, 0f, offsetY, 0f, 0f, scaleZ, offsetZ, 0f, 0f, 0f, 1f);
    Matrix4f result = new Matrix4f();
    result.set(cropMatrix);
    result.multLocal(projMatrix);
    vars.release();
    shadowCam.setProjectionMatrix(result);
}
Also used : Geometry(com.jme3.scene.Geometry) Matrix4f(com.jme3.math.Matrix4f) Spatial(com.jme3.scene.Spatial) BoundingBox(com.jme3.bounding.BoundingBox) Vector3f(com.jme3.math.Vector3f) BoundingVolume(com.jme3.bounding.BoundingVolume) TempVars(com.jme3.util.TempVars)

Example 25 with Camera

use of com.jme3.renderer.Camera in project jmonkeyengine by jMonkeyEngine.

the class DirectionalLightShadowRenderer method getOccludersToRender.

@Override
protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders) {
    // update frustum points based on current camera and split
    ShadowUtil.updateFrustumPoints(viewPort.getCamera(), splitsArray[shadowMapIndex], splitsArray[shadowMapIndex + 1], 1.0f, points);
    //Updating shadow cam with curent split frustra
    if (lightReceivers.size() == 0) {
        for (Spatial scene : viewPort.getScenes()) {
            ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, lightReceivers);
        }
    }
    ShadowUtil.updateShadowCamera(viewPort, lightReceivers, shadowCam, points, shadowMapOccluders, stabilize ? shadowMapSize : 0);
    return shadowMapOccluders;
}
Also used : Spatial(com.jme3.scene.Spatial)

Aggregations

Camera (com.jme3.renderer.Camera)63 Vector3f (com.jme3.math.Vector3f)51 Material (com.jme3.material.Material)26 Geometry (com.jme3.scene.Geometry)26 Quaternion (com.jme3.math.Quaternion)23 Spatial (com.jme3.scene.Spatial)19 TempVars (com.jme3.util.TempVars)16 Box (com.jme3.scene.shape.Box)13 ViewPort (com.jme3.renderer.ViewPort)11 Node (com.jme3.scene.Node)11 DirectionalLight (com.jme3.light.DirectionalLight)10 FrameBuffer (com.jme3.texture.FrameBuffer)10 Texture (com.jme3.texture.Texture)10 FilterPostProcessor (com.jme3.post.FilterPostProcessor)9 Texture2D (com.jme3.texture.Texture2D)9 ArrayList (java.util.ArrayList)9 TerrainQuad (com.jme3.terrain.geomipmap.TerrainQuad)8 AbstractHeightMap (com.jme3.terrain.heightmap.AbstractHeightMap)8 ImageBasedHeightMap (com.jme3.terrain.heightmap.ImageBasedHeightMap)8 CameraNode (com.jme3.scene.CameraNode)7