Search in sources :

Example 1 with GeometryList

use of com.jme3.renderer.queue.GeometryList in project jmonkeyengine by jMonkeyEngine.

the class PssmShadowRenderer method setMatParams.

private void setMatParams() {
    GeometryList l = lightReceivers;
    //iteration throught all the geometries of the list to gather the materials
    matCache.clear();
    for (int i = 0; i < l.size(); i++) {
        Material mat = l.get(i).getMaterial();
        //checking if the material has the post technique and adding it to the material cache
        if (mat.getMaterialDef().getTechniqueDefs(postTechniqueName) != null) {
            if (!matCache.contains(mat)) {
                matCache.add(mat);
            }
        } else {
            needsfallBackMaterial = true;
        }
    }
    //iterating through the mat cache and setting the parameters
    for (Material mat : matCache) {
        mat.setColor("Splits", splits);
        mat.setFloat("ShadowMapSize", shadowMapSize);
        for (int j = 0; j < nbSplits; j++) {
            mat.setMatrix4("LightViewProjectionMatrix" + j, lightViewProjectionsMatrices[j]);
        }
        for (int j = 0; j < nbSplits; j++) {
            mat.setTexture("ShadowMap" + j, shadowMaps[j]);
        }
        mat.setBoolean("HardwareShadows", compareMode == CompareMode.Hardware);
        mat.setInt("FilterMode", filterMode.ordinal());
        mat.setFloat("PCFEdge", edgesThickness);
        mat.setFloat("ShadowIntensity", shadowIntensity);
        if (fadeInfo != null) {
            mat.setVector2("FadeInfo", fadeInfo);
        }
    }
    applyHWShadows = false;
    applyFilterMode = false;
    applyPCFEdge = false;
    applyShadowIntensity = false;
    applyFadeInfo = false;
    //so we fall back to the forced material solution (transparent shadows won't be supported for these objects)
    if (needsfallBackMaterial) {
        setPostShadowParams();
    }
}
Also used : GeometryList(com.jme3.renderer.queue.GeometryList) Material(com.jme3.material.Material)

Example 2 with GeometryList

use of com.jme3.renderer.queue.GeometryList 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 3 with GeometryList

use of com.jme3.renderer.queue.GeometryList 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 4 with GeometryList

use of com.jme3.renderer.queue.GeometryList 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 5 with GeometryList

use of com.jme3.renderer.queue.GeometryList 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

Geometry (com.jme3.scene.Geometry)6 Spatial (com.jme3.scene.Spatial)5 BoundingBox (com.jme3.bounding.BoundingBox)4 Material (com.jme3.material.Material)4 BoundingVolume (com.jme3.bounding.BoundingVolume)3 Camera (com.jme3.renderer.Camera)3 TempVars (com.jme3.util.TempVars)3 Matrix4f (com.jme3.math.Matrix4f)2 GeometryList (com.jme3.renderer.queue.GeometryList)2 Vector3f (com.jme3.math.Vector3f)1 Node (com.jme3.scene.Node)1 HashSet (java.util.HashSet)1