From ed369135fa471495b9d6190e31a9d1094cc628d7 Mon Sep 17 00:00:00 2001 From: Bebul Date: Fri, 20 Feb 2015 11:58:49 +0100 Subject: [PATCH] fix renderShadow optimization to work on multiple scenes attached to viewPort properly --- .../main/java/com/jme3/renderer/RenderManager.java | 2 -- .../java/com/jme3/renderer/queue/RenderQueue.java | 9 --------- .../java/com/jme3/shadow/AbstractShadowRenderer.java | 6 +++--- .../java/com/jme3/shadow/BasicShadowRenderer.java | 7 +++++-- .../jme3/shadow/DirectionalLightShadowRenderer.java | 11 ++++++++--- .../com/jme3/shadow/PointLightShadowRenderer.java | 9 +++++++-- .../main/java/com/jme3/shadow/PssmShadowRenderer.java | 6 ++++-- .../src/main/java/com/jme3/shadow/ShadowUtil.java | 8 ++++++-- .../java/com/jme3/shadow/SpotLightShadowRenderer.java | 9 +++++++-- 9 files changed, 40 insertions(+), 27 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java b/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java index 89d41761c..2c0c8a4b8 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java +++ b/jme3-core/src/main/java/com/jme3/renderer/RenderManager.java @@ -658,8 +658,6 @@ public class RenderManager { public void renderScene(Spatial scene, ViewPort vp) { //reset of the camera plane state for proper culling (must be 0 for the first note of the scene to be rendered) vp.getCamera().setPlaneState(0); - //remember the scene for possible later use - vp.getQueue().setRootScene(scene); //rendering the scene renderSubScene(scene, vp); } diff --git a/jme3-core/src/main/java/com/jme3/renderer/queue/RenderQueue.java b/jme3-core/src/main/java/com/jme3/renderer/queue/RenderQueue.java index 9bd46f30f..ea4215d6c 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/queue/RenderQueue.java +++ b/jme3-core/src/main/java/com/jme3/renderer/queue/RenderQueue.java @@ -51,7 +51,6 @@ public class RenderQueue { private GeometryList translucentList; private GeometryList skyList; private GeometryList shadowRecv; - private Spatial rootScene = null; /** * Creates a new RenderQueue, the default {@link GeometryComparator comparators} @@ -337,14 +336,6 @@ public class RenderQueue { } } - public void setRootScene(Spatial rs) { - rootScene = rs; - } - - public Spatial getRootScene() { - return rootScene; - } - public void clear() { opaqueList.clear(); guiList.clear(); diff --git a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java index 545dff9e4..b78d1e3bd 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/AbstractShadowRenderer.java @@ -489,9 +489,6 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable //rendering the post shadow pass viewPort.getQueue().renderShadowQueue(lightReceivers, renderManager, cam, false); - if (flushQueues) { - sceneReceivers.clear(); - } //resetting renderManager settings renderManager.setForcedTechnique(null); @@ -502,6 +499,9 @@ public abstract class AbstractShadowRenderer implements SceneProcessor, Savable clearMatParams(); } + if (flushQueues) { + sceneReceivers.clear(); + } } /** diff --git a/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java index bc86bd210..bc4273db7 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/BasicShadowRenderer.java @@ -43,6 +43,7 @@ import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.OpaqueComparator; import com.jme3.renderer.queue.RenderQueue; import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Spatial; import com.jme3.texture.FrameBuffer; import com.jme3.texture.Image.Format; import com.jme3.texture.Texture2D; @@ -146,7 +147,9 @@ public class BasicShadowRenderer implements SceneProcessor { } public void postQueue(RenderQueue rq) { - ShadowUtil.getGeometriesInCamFrustum(rq.getRootScene(), viewPort.getCamera(), ShadowMode.Receive, lightReceivers); + for (Spatial scene : viewPort.getScenes()) { + ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), ShadowMode.Receive, lightReceivers); + } // update frustum points based on current camera Camera viewCam = viewPort.getCamera(); @@ -174,7 +177,7 @@ public class BasicShadowRenderer implements SceneProcessor { shadowCam.updateViewProjection(); // render shadow casters to shadow map - ShadowUtil.updateShadowCamera(rq.getRootScene(), lightReceivers, shadowCam, points, shadowOccluders, shadowMapSize); + ShadowUtil.updateShadowCamera(viewPort, lightReceivers, shadowCam, points, shadowOccluders, shadowMapSize); if (shadowOccluders.size() == 0) { noOccluders = true; return; diff --git a/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java index f5f0f1b92..1c5b2617c 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/DirectionalLightShadowRenderer.java @@ -45,6 +45,7 @@ import com.jme3.renderer.Camera; import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.RenderQueue; import com.jme3.scene.Node; +import com.jme3.scene.Spatial; import java.io.IOException; /** @@ -181,9 +182,11 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { //Updating shadow cam with curent split frustra if (sceneReceivers.size()==0) { - ShadowUtil.getGeometriesInCamFrustum(viewPort.getQueue().getRootScene(), viewPort.getCamera(), RenderQueue.ShadowMode.Receive, sceneReceivers); + for (Spatial scene : viewPort.getScenes()) { + ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, sceneReceivers); + } } - ShadowUtil.updateShadowCamera(viewPort.getQueue().getRootScene(), sceneReceivers, shadowCam, points, shadowMapOccluders, stabilize?shadowMapSize:0); + ShadowUtil.updateShadowCamera(viewPort, sceneReceivers, shadowCam, points, shadowMapOccluders, stabilize?shadowMapSize:0); return shadowMapOccluders; } @@ -191,7 +194,9 @@ public class DirectionalLightShadowRenderer extends AbstractShadowRenderer { @Override GeometryList getReceivers(GeometryList sceneReceivers, GeometryList lightReceivers) { if (sceneReceivers.size()==0) { - ShadowUtil.getGeometriesInCamFrustum(viewPort.getQueue().getRootScene(), viewPort.getCamera(), RenderQueue.ShadowMode.Receive, sceneReceivers); + for (Spatial scene : viewPort.getScenes()) { + ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), RenderQueue.ShadowMode.Receive, sceneReceivers); + } } lightReceivers = sceneReceivers; return sceneReceivers; diff --git a/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java index df09adbe9..4ded98b23 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/PointLightShadowRenderer.java @@ -44,6 +44,7 @@ import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.RenderQueue; import com.jme3.scene.Geometry; import com.jme3.scene.Node; +import com.jme3.scene.Spatial; import com.jme3.util.TempVars; import java.io.IOException; @@ -131,14 +132,18 @@ public class PointLightShadowRenderer extends AbstractShadowRenderer { @Override protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders) { - ShadowUtil.getGeometriesInCamFrustum(viewPort.getQueue().getRootScene(), shadowCams[shadowMapIndex], RenderQueue.ShadowMode.Cast, shadowMapOccluders); + for (Spatial scene : viewPort.getScenes()) { + ShadowUtil.getGeometriesInCamFrustum(scene, shadowCams[shadowMapIndex], RenderQueue.ShadowMode.Cast, shadowMapOccluders); + } return shadowMapOccluders; } @Override GeometryList getReceivers(GeometryList sceneReceivers, GeometryList lightReceivers) { lightReceivers.clear(); - ShadowUtil.getLitGeometriesInViewPort(viewPort.getQueue().getRootScene(), viewPort.getCamera(), shadowCams, RenderQueue.ShadowMode.Receive, lightReceivers); + for (Spatial scene : viewPort.getScenes()) { + ShadowUtil.getLitGeometriesInViewPort(scene, viewPort.getCamera(), shadowCams, RenderQueue.ShadowMode.Receive, lightReceivers); + } return lightReceivers; } diff --git a/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java index f1985df9d..182052e13 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/PssmShadowRenderer.java @@ -387,7 +387,9 @@ public class PssmShadowRenderer implements SceneProcessor { @SuppressWarnings("fallthrough") public void postQueue(RenderQueue rq) { - ShadowUtil.getGeometriesInCamFrustum(rq.getRootScene(), viewPort.getCamera(), ShadowMode.Receive, lightReceivers); + for (Spatial scene : viewPort.getScenes()) { + ShadowUtil.getGeometriesInCamFrustum(scene, viewPort.getCamera(), ShadowMode.Receive, lightReceivers); + } Camera viewCam = viewPort.getCamera(); @@ -431,7 +433,7 @@ public class PssmShadowRenderer implements SceneProcessor { ShadowUtil.updateFrustumPoints(viewCam, splitsArray[i], splitsArray[i + 1], 1.0f, points); //Updating shadow cam with curent split frustra - ShadowUtil.updateShadowCamera(rq.getRootScene(), lightReceivers, shadowCam, points, splitOccluders, shadowMapSize); + ShadowUtil.updateShadowCamera(viewPort, lightReceivers, shadowCam, points, splitOccluders, shadowMapSize); //saving light view projection matrix for this split lightViewProjectionsMatrices[i].set(shadowCam.getViewProjectionMatrix()); diff --git a/jme3-core/src/main/java/com/jme3/shadow/ShadowUtil.java b/jme3-core/src/main/java/com/jme3/shadow/ShadowUtil.java index b4f41e0a4..d97a354f9 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/ShadowUtil.java +++ b/jme3-core/src/main/java/com/jme3/shadow/ShadowUtil.java @@ -39,6 +39,7 @@ import com.jme3.math.Transform; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.renderer.Camera; +import com.jme3.renderer.ViewPort; import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.RenderQueue; import com.jme3.scene.Geometry; @@ -452,7 +453,7 @@ public class ShadowUtil { * contain the eye camera frustum corners) and the shadow occluder objects * collected through the traverse of the scene hierarchy */ - public static void updateShadowCamera(Spatial rootScene, + public static void updateShadowCamera(ViewPort viewPort, GeometryList receivers, Camera shadowCam, Vector3f[] points, @@ -496,7 +497,10 @@ public class ShadowUtil { // collect splitOccluders through scene recursive traverse OccludersExtractor occExt = new OccludersExtractor(viewProjMatrix, casterCount, splitBB, casterBB, splitOccluders, vars); - casterCount = occExt.addOccluders(rootScene); + 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) { diff --git a/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java b/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java index c8207f615..e7a3a5407 100644 --- a/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java +++ b/jme3-core/src/main/java/com/jme3/shadow/SpotLightShadowRenderer.java @@ -45,6 +45,7 @@ import com.jme3.renderer.Camera; import com.jme3.renderer.queue.GeometryList; import com.jme3.renderer.queue.RenderQueue; import com.jme3.scene.Node; +import com.jme3.scene.Spatial; import com.jme3.util.TempVars; import java.io.IOException; @@ -143,7 +144,9 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer { @Override protected GeometryList getOccludersToRender(int shadowMapIndex, GeometryList shadowMapOccluders) { - ShadowUtil.getGeometriesInCamFrustum(viewPort.getQueue().getRootScene(), shadowCam, RenderQueue.ShadowMode.Cast, shadowMapOccluders); + for (Spatial scene : viewPort.getScenes()) { + ShadowUtil.getGeometriesInCamFrustum(scene, shadowCam, RenderQueue.ShadowMode.Cast, shadowMapOccluders); + } return shadowMapOccluders; } @@ -152,7 +155,9 @@ public class SpotLightShadowRenderer extends AbstractShadowRenderer { lightReceivers.clear(); Camera[] cameras = new Camera[1]; cameras[0] = shadowCam; - ShadowUtil.getLitGeometriesInViewPort(viewPort.getQueue().getRootScene(), viewPort.getCamera(), cameras, RenderQueue.ShadowMode.Receive, lightReceivers); + for (Spatial scene : viewPort.getScenes()) { + ShadowUtil.getLitGeometriesInViewPort(scene, viewPort.getCamera(), cameras, RenderQueue.ShadowMode.Receive, lightReceivers); + } return lightReceivers; }