Search in sources :

Example 11 with ViewPort

use of com.jme3.renderer.ViewPort 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 12 with ViewPort

use of com.jme3.renderer.ViewPort 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 13 with ViewPort

use of com.jme3.renderer.ViewPort 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)

Example 14 with ViewPort

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

the class TestDirectionalLightShadow method initInputs.

private void initInputs() {
    inputManager.addMapping("ThicknessUp", new KeyTrigger(KeyInput.KEY_Y));
    inputManager.addMapping("ThicknessDown", new KeyTrigger(KeyInput.KEY_H));
    inputManager.addMapping("lambdaUp", new KeyTrigger(KeyInput.KEY_U));
    inputManager.addMapping("lambdaDown", new KeyTrigger(KeyInput.KEY_J));
    inputManager.addMapping("switchGroundMat", new KeyTrigger(KeyInput.KEY_M));
    inputManager.addMapping("debug", new KeyTrigger(KeyInput.KEY_X));
    inputManager.addMapping("stabilize", new KeyTrigger(KeyInput.KEY_B));
    inputManager.addMapping("distance", new KeyTrigger(KeyInput.KEY_N));
    inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_NUMPAD8));
    inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_NUMPAD2));
    inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_NUMPAD6));
    inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_NUMPAD4));
    inputManager.addMapping("fwd", new KeyTrigger(KeyInput.KEY_PGUP));
    inputManager.addMapping("back", new KeyTrigger(KeyInput.KEY_PGDN));
    inputManager.addMapping("pp", new KeyTrigger(KeyInput.KEY_P));
    inputManager.addMapping("backShadows", new KeyTrigger(KeyInput.KEY_K));
    inputManager.addListener(this, "lambdaUp", "lambdaDown", "ThicknessUp", "ThicknessDown", "switchGroundMat", "debug", "up", "down", "right", "left", "fwd", "back", "pp", "stabilize", "distance", "ShadowUp", "ShadowDown", "backShadows");
    ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, dlsr, dlsf, guiNode, inputManager, viewPort);
    inputManager.addListener(this, "Size+", "Size-");
    inputManager.addMapping("Size+", new KeyTrigger(KeyInput.KEY_W));
    inputManager.addMapping("Size-", new KeyTrigger(KeyInput.KEY_S));
    shadowStabilizationText = new BitmapText(guiFont, false);
    shadowStabilizationText.setSize(guiFont.getCharSet().getRenderedSize() * 0.75f);
    shadowStabilizationText.setText("(b:on/off) Shadow stabilization : " + dlsr.isEnabledStabilization());
    shadowStabilizationText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 100, 0);
    guiNode.attachChild(shadowStabilizationText);
    shadowZfarText = new BitmapText(guiFont, false);
    shadowZfarText.setSize(guiFont.getCharSet().getRenderedSize() * 0.75f);
    shadowZfarText.setText("(n:on/off) Shadow extend to 500 and fade to 50 : " + (dlsr.getShadowZExtend() > 0));
    shadowZfarText.setLocalTranslation(10, viewPort.getCamera().getHeight() - 120, 0);
    guiNode.attachChild(shadowZfarText);
}
Also used : BitmapText(com.jme3.font.BitmapText) KeyTrigger(com.jme3.input.controls.KeyTrigger)

Example 15 with ViewPort

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

the class TestPointLightShadows method simpleInitApp.

@Override
public void simpleInitApp() {
    flyCam.setMoveSpeed(10);
    cam.setLocation(new Vector3f(0.040581334f, 1.7745866f, 6.155161f));
    cam.setRotation(new Quaternion(4.3868728E-5f, 0.9999293f, -0.011230096f, 0.0039059948f));
    al = new AmbientLight(ColorRGBA.White.mult(0.02f));
    rootNode.addLight(al);
    Node scene = (Node) assetManager.loadModel("Models/Test/CornellBox.j3o");
    scene.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
    rootNode.attachChild(scene);
    rootNode.getChild("Cube").setShadowMode(RenderQueue.ShadowMode.Receive);
    lightNode = (Node) rootNode.getChild("Lamp");
    Geometry lightMdl = new Geometry("Light", new Sphere(10, 10, 0.1f));
    //Geometry  lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f));
    lightMdl.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m"));
    lightMdl.setShadowMode(RenderQueue.ShadowMode.Off);
    lightNode.attachChild(lightMdl);
    //lightMdl.setLocalTranslation(lightNode.getLocalTranslation());
    Geometry box = new Geometry("box", new Box(0.2f, 0.2f, 0.2f));
    //Geometry  lightMdl = new Geometry("Light", new Box(.1f,.1f,.1f));
    box.setMaterial(assetManager.loadMaterial("Common/Materials/RedColor.j3m"));
    box.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
    rootNode.attachChild(box);
    box.setLocalTranslation(-1f, 0.5f, -2);
    plsr = new PointLightShadowRenderer(assetManager, SHADOWMAP_SIZE);
    plsr.setLight((PointLight) scene.getLocalLightList().get(0));
    plsr.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
    plsr.setShadowZExtend(15);
    plsr.setShadowZFadeLength(5);
    plsr.setShadowIntensity(0.9f);
    // plsr.setFlushQueues(false);
    //plsr.displayFrustum();
    plsr.displayDebug();
    viewPort.addProcessor(plsr);
    plsf = new PointLightShadowFilter(assetManager, SHADOWMAP_SIZE);
    plsf.setLight((PointLight) scene.getLocalLightList().get(0));
    plsf.setShadowZExtend(15);
    plsf.setShadowZFadeLength(5);
    plsf.setShadowIntensity(0.8f);
    plsf.setEdgeFilteringMode(EdgeFilteringMode.PCF4);
    plsf.setEnabled(false);
    FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
    fpp.addFilter(plsf);
    viewPort.addProcessor(fpp);
    inputManager.addListener(this, "ShadowUp", "ShadowDown");
    ShadowTestUIManager uiMan = new ShadowTestUIManager(assetManager, plsr, plsf, guiNode, inputManager, viewPort);
}
Also used : Geometry(com.jme3.scene.Geometry) Sphere(com.jme3.scene.shape.Sphere) Quaternion(com.jme3.math.Quaternion) Vector3f(com.jme3.math.Vector3f) Node(com.jme3.scene.Node) PointLightShadowFilter(com.jme3.shadow.PointLightShadowFilter) Box(com.jme3.scene.shape.Box) PointLightShadowRenderer(com.jme3.shadow.PointLightShadowRenderer) FilterPostProcessor(com.jme3.post.FilterPostProcessor) AmbientLight(com.jme3.light.AmbientLight)

Aggregations

Material (com.jme3.material.Material)29 Camera (com.jme3.renderer.Camera)19 FrameBuffer (com.jme3.texture.FrameBuffer)19 Geometry (com.jme3.scene.Geometry)18 Texture2D (com.jme3.texture.Texture2D)17 ViewPort (com.jme3.renderer.ViewPort)16 Vector3f (com.jme3.math.Vector3f)14 Spatial (com.jme3.scene.Spatial)12 Box (com.jme3.scene.shape.Box)9 Node (com.jme3.scene.Node)8 FilterPostProcessor (com.jme3.post.FilterPostProcessor)7 Renderer (com.jme3.renderer.Renderer)7 Picture (com.jme3.ui.Picture)6 KeyTrigger (com.jme3.input.controls.KeyTrigger)5 Quaternion (com.jme3.math.Quaternion)5 DirectionalLight (com.jme3.light.DirectionalLight)4 SceneProcessor (com.jme3.post.SceneProcessor)4 Sphere (com.jme3.scene.shape.Sphere)4 ActionListener (com.jme3.input.controls.ActionListener)3 Vector2f (com.jme3.math.Vector2f)3