@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 current split frusta 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; }
public void makeCamFrustum() { Vector3f[] points = new Vector3f[8]; for (int i = 0; i < 8; i++) { points[i] = new Vector3f(); } ShadowUtil.updateFrustumPoints2(frustumCam, points); WireFrustum frustumShape = new WireFrustum(points); frustumGeom = new Geometry("frustum", frustumShape); frustumGeom.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); rootNode.attachChild(frustumGeom); }
/** * Compute the Zfar in the model vieuw to adjust the Zfar distance for the splits calculation */ public static float computeZFar(GeometryList occ, GeometryList recv, Camera cam) { Matrix4f mat = cam.getViewMatrix(); BoundingBox bbOcc = ShadowUtil.computeUnionBound(occ, mat); BoundingBox bbRecv = ShadowUtil.computeUnionBound(recv, mat); return min(max(bbOcc.getZExtent() - bbOcc.getCenter().z, bbRecv.getZExtent() - bbRecv.getCenter().z), cam.getFrustumFar()); } }
@SuppressWarnings("fallthrough") public void postQueue(RenderQueue rq) { for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), ShadowMode.Receive, lightReceivers); ShadowUtil.updateFrustumPoints(viewCam, frustumNear, zFar, 1.0f, points); ShadowUtil.updateFrustumPoints(viewCam, splitsArray[i], splitsArray[i + 1], 1.0f, points); ShadowUtil.updateShadowCamera(viewPort, lightReceivers, shadowCam, points, splitOccluders, shadowMapSize); ShadowUtil.updateFrustumPoints2(shadowCam, points); ((Node) viewPort.getScenes().get(0)).attachChild(createFrustum(points, i));
ShadowUtil.updateFrustumPoints(viewCam, frustumNear, zFar, 1.0f, points); ShadowUtil.updateFrustumPoints(viewCam, splitsArray[i], splitsArray[i + 1], 1.0f, points); ShadowUtil.updateShadowCamera(occluders, receivers, shadowCam, points, splitOccluders);
@Override protected void updateShadowCams(Camera viewCam) { if (light == null) { logger.warning("The light can't be null for a " + getClass().getName()); return; } 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.setFrustumPerspective(light.getSpotOuterAngle() * FastMath.RAD_TO_DEG * 2.0f, 1, 1f, light.getSpotRange()); shadowCam.getRotation().lookAt(light.getDirection(), shadowCam.getUp()); shadowCam.setLocation(light.getPosition()); shadowCam.update(); shadowCam.updateViewProjection(); }
@Override protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders) { for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getGeometriesInCamFrustum(scene, shadowCams[shadowMapIndex], RenderQueue.ShadowMode.Cast, shadowMapOccluders); } return shadowMapOccluders; }
BoundingBox splitBB = computeBoundForPoints(points, viewProjMatrix);
BoundingBox splitBB = computeBoundForPoints(points, viewProjMatrix); BoundingBox casterBB = computeUnionBound(visOccList); BoundingBox receiverBB = computeUnionBound(visRecvList);
/** * Helper function used to recursively populate the outputGeometryList * with geometry children of scene node * * @param camera * @param scene * @param outputGeometryList */ private static void addGeometriesInCamFrustumFromNode(Camera camera, Node scene, RenderQueue.ShadowMode mode, GeometryList outputGeometryList) { if (scene.getCullHint() == Spatial.CullHint.Always) return; camera.setPlaneState(0); if (camera.contains(scene.getWorldBound()) != Camera.FrustumIntersect.Outside) { for (Spatial child: scene.getChildren()) { if (child instanceof Node) addGeometriesInCamFrustumFromNode(camera, (Node)child, mode, outputGeometryList); else if (child instanceof Geometry && child.getCullHint() != Spatial.CullHint.Always) { camera.setPlaneState(0); if (checkShadowMode(child.getShadowMode(), mode) && !((Geometry)child).isGrouped() && camera.contains(child.getWorldBound()) != Camera.FrustumIntersect.Outside) { outputGeometryList.add((Geometry)child); } } } } }
addGeometriesInCamFrustumAndViewPortFromNode(vpCamera, cameras, child, mode, outputGeometryList); if (checkShadowMode(scene.getShadowMode(), mode) && !((Geometry)scene).isGrouped() ) { outputGeometryList.add((Geometry)scene);
/** * Updates the shadow camera to properly contain the given * points (which contain the eye camera frustum corners) and the * shadow occluder objects. * * @param occluders * @param lightCam * @param points */ public static void updateShadowCamera(GeometryList occluders, GeometryList receivers, Camera shadowCam, Vector3f[] points) { updateShadowCamera(occluders, receivers, shadowCam, points, null); }
@Override protected void getReceivers(GeometryList lightReceivers) { lightReceivers.clear(); for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getLitGeometriesInViewPort(scene, viewPort.getCamera(), shadowCams, RenderQueue.ShadowMode.Receive, lightReceivers); } }
/** * Populates the outputGeometryList with the geometries of the children * of OccludersExtractor.rootScene node that are both in the frustum of the given vpCamera and some camera inside cameras array. * The array of cameras must be initialized to represent the light viewspace of some light like pointLight or spotLight * * @param camera the viewPort camera * @param cameras the camera array to check geometries against, representing the light viewspace * @param outputGeometryList the output list of all geometries that are in the camera frustum */ public static void getLitGeometriesInViewPort(Spatial rootScene, Camera vpCamera, Camera[] cameras, RenderQueue.ShadowMode mode, GeometryList outputGeometryList) { if (rootScene != null && rootScene instanceof Node) { addGeometriesInCamFrustumAndViewPortFromNode(vpCamera, cameras, (Node)rootScene, mode, outputGeometryList); } } /**
/** * Populates the outputGeometryList with the rootScene children geometries * that are in the frustum of the given camera * * @param rootScene the rootNode of the scene to traverse * @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(Spatial rootScene, Camera camera, RenderQueue.ShadowMode mode, GeometryList outputGeometryList) { if (rootScene != null && rootScene instanceof Node) { int planeState = camera.getPlaneState(); addGeometriesInCamFrustumFromNode(camera, (Node)rootScene, mode, outputGeometryList); camera.setPlaneState(planeState); } }
@SuppressWarnings("fallthrough") public void postQueue(RenderQueue rq) { for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), ShadowMode.Receive, lightReceivers); ShadowUtil.updateFrustumPoints(viewCam, frustumNear, zFar, 1.0f, points); ShadowUtil.updateFrustumPoints(viewCam, splitsArray[i], splitsArray[i + 1], 1.0f, points); ShadowUtil.updateShadowCamera(viewPort, lightReceivers, shadowCam, points, splitOccluders, shadowMapSize); ShadowUtil.updateFrustumPoints2(shadowCam, points); ((Node) viewPort.getScenes().get(0)).attachChild(createFrustum(points, i));
ShadowUtil.updateFrustumPoints(viewCam, viewCam.getFrustumNear(), viewCam.getFrustumFar(), ShadowUtil.updateShadowCamera(occluders, receivers, shadowCam, points);
ShadowUtil.updateFrustumPoints(viewCam, frustumNear, zFar, 1.0f, points);
@Override protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders) { for (Spatial scene : viewPort.getScenes()) { ShadowUtil.getGeometriesInCamFrustum(scene, shadowCam, RenderQueue.ShadowMode.Cast, shadowMapOccluders); } return shadowMapOccluders; }
Matrix4f projMatrix = shadowCam.getProjectionMatrix(); BoundingBox splitBB = computeBoundForPoints(points, viewProjMatrix);