Kirill Vainer 8 лет назад
Родитель
Сommit
47b34c6de5

+ 3 - 5
jme3-core/src/main/java/com/jme3/shadow/next/PreShadowArrayRenderer.java

@@ -148,16 +148,14 @@ public class PreShadowArrayRenderer implements SceneProcessor {
                         array,
                         nextArraySlice,
                         textureSize,
-                        directionalParams.getNumSplits(),
-                        points);
+                        directionalParams.getNumSplits());
                 break;
             case Spot:
                 shadowMap = new SpotArrayShadowMap(
                         (SpotLight) light,
                         array,
                         nextArraySlice,
-                        textureSize,
-                        points);
+                        textureSize);
                 break;
             default:
                 throw new UnsupportedOperationException();
@@ -202,7 +200,7 @@ public class PreShadowArrayRenderer implements SceneProcessor {
             switch (shadowMap.getLightType()) {
                 case Directional:
                     DirectionalArrayShadowMap directionalShadow = (DirectionalArrayShadowMap) shadowMap;
-                    directionalShadow.renderShadowMap(renderManager, viewPort, directionalParams, shadowCasters);
+                    directionalShadow.renderShadowMap(renderManager, viewPort, directionalParams, shadowCasters, points);
                     break;
                 case Spot:
                     SpotArrayShadowMap spotShadow = (SpotArrayShadowMap) shadowMap;

+ 20 - 10
jme3-core/src/main/java/com/jme3/shadow/next/array/BaseArrayShadowMapSlice.java

@@ -33,7 +33,6 @@ package com.jme3.shadow.next.array;
 
 import com.jme3.light.Light;
 import com.jme3.math.Matrix4f;
-import com.jme3.math.Vector3f;
 import com.jme3.renderer.Camera;
 import com.jme3.renderer.RenderManager;
 import com.jme3.renderer.Renderer;
@@ -51,12 +50,18 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
 
     protected final FrameBuffer frameBuffer;
     protected final Camera shadowCamera;
-    protected final Vector3f[] points;
     protected final Matrix4f biasedViewProjectionMatrix = new Matrix4f();
 
-    public BaseArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) {
+    protected boolean fbNeedClear = true;
+
+    public BaseArrayShadowMapSlice(TextureArray array, int layer, int textureSize, boolean useBorder) {
         this.shadowCamera = new Camera(textureSize, textureSize);
-        this.shadowCamera.setParallelProjection(true);
+
+        if (useBorder) {
+            float onePx = 1f / textureSize;
+            this.shadowCamera.setViewPort(onePx, 1f - onePx, onePx, 1f - onePx);
+        }
+
         this.frameBuffer = new FrameBuffer(textureSize, textureSize, 1);
 
         Image image = array.getImage();
@@ -64,7 +69,6 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
         image.addData(null);
 
         this.frameBuffer.setDepthTexture(array, layer);
-        this.points = points;
     }
 
     @Override
@@ -76,12 +80,18 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
     public void renderShadowMap(RenderManager renderManager, Light light, ViewPort viewPort, GeometryList shadowCasters) {
         Renderer renderer = renderManager.getRenderer();
 
-        renderer.setFrameBuffer(frameBuffer);
-        renderManager.setCamera(shadowCamera, false);
-        renderer.clearBuffers(false, true, false);
+        if (fbNeedClear) {
+            renderer.setFrameBuffer(frameBuffer);
+            renderer.clearBuffers(false, true, false);
+            fbNeedClear = false;
+        }
+
+        if (shadowCasters.size() > 0) {
+            renderManager.setCamera(shadowCamera, false);
+            viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true);
+            fbNeedClear = true;
+        }
 
-        viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true);
-        
         BIAS_MATRIX.mult(shadowCamera.getViewProjectionMatrix(), biasedViewProjectionMatrix);
     }
 }

+ 4 - 4
jme3-core/src/main/java/com/jme3/shadow/next/array/DirectionalArrayShadowMap.java

@@ -48,23 +48,23 @@ public class DirectionalArrayShadowMap extends BaseArrayShadowMap<DirectionalArr
     private final DirectionalLight light;
     private final Vector3f projectionSplitPositions = new Vector3f();
 
-    public DirectionalArrayShadowMap(DirectionalLight light, TextureArray array, int firstArraySlice, int textureSize, int numSplits, Vector3f[] points) {
+    public DirectionalArrayShadowMap(DirectionalLight light, TextureArray array, int firstArraySlice, int textureSize, int numSplits) {
         super(array, firstArraySlice);
         this.light = light;
         this.slices = new DirectionalArrayShadowMapSlice[numSplits];
         for (int i = 0; i < numSplits; i++) {
-            this.slices[i] = new DirectionalArrayShadowMapSlice(array, firstArraySlice + i, textureSize, points);
+            this.slices[i] = new DirectionalArrayShadowMapSlice(array, firstArraySlice + i, textureSize);
         }
     }
 
-    public void renderShadowMap(RenderManager renderManager, ViewPort viewPort, DirectionalShadowParameters params, GeometryList shadowCasters) {
+    public void renderShadowMap(RenderManager renderManager, ViewPort viewPort, DirectionalShadowParameters params, GeometryList shadowCasters, Vector3f[] points) {
         projectionSplitPositions.set(params.getProjectionSplitPositions());
         float[] splitPositionsViewSpace = params.getSplitPositions();
         for (int i = 0; i < slices.length; i++) {
             float near = splitPositionsViewSpace[i];
             float far = splitPositionsViewSpace[i + 1];
             shadowCasters.clear();
-            slices[i].updateShadowCamera(viewPort, light, shadowCasters, near, far);
+            slices[i].updateShadowCamera(viewPort, light, shadowCasters, near, far, points);
             slices[i].renderShadowMap(renderManager, light, viewPort, shadowCasters);
         }
     }

+ 6 - 7
jme3-core/src/main/java/com/jme3/shadow/next/array/DirectionalArrayShadowMapSlice.java

@@ -39,13 +39,12 @@ import com.jme3.shadow.ShadowUtil;
 import com.jme3.texture.TextureArray;
 
 /**
- *
  * @author Kirill Vainer
  */
 public class DirectionalArrayShadowMapSlice extends BaseArrayShadowMapSlice<DirectionalLight> {
 
-    public DirectionalArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) {
-        super(array, layer, textureSize, points);
+    public DirectionalArrayShadowMapSlice(TextureArray array, int layer, int textureSize) {
+        super(array, layer, textureSize, true);
         this.shadowCamera.setParallelProjection(true);
     }
 
@@ -54,12 +53,12 @@ public class DirectionalArrayShadowMapSlice extends BaseArrayShadowMapSlice<Dire
             DirectionalLight light,
             GeometryList shadowCasters,
             float near,
-            float far) {
-        
-        ShadowUtil.updateFrustumPoints(viewPort.getCamera(), near, far, points);
+            float far,
+            Vector3f[] points) {
         shadowCamera.lookAtDirection(light.getDirection(), shadowCamera.getUp());
-        
+
         int textureSize = frameBuffer.getWidth();
+        ShadowUtil.updateFrustumPoints(viewPort.getCamera(), near, far, points);
         ShadowUtil.updateShadowCamera(viewPort, null, shadowCamera, points, shadowCasters, textureSize);
     }
 

+ 2 - 3
jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java

@@ -33,7 +33,6 @@ package com.jme3.shadow.next.array;
 
 import com.jme3.light.Light;
 import com.jme3.light.SpotLight;
-import com.jme3.math.Vector3f;
 import com.jme3.renderer.RenderManager;
 import com.jme3.renderer.ViewPort;
 import com.jme3.renderer.queue.GeometryList;
@@ -46,11 +45,11 @@ public class SpotArrayShadowMap extends BaseArrayShadowMap<SpotArrayShadowMapSli
 
     private final SpotLight light;
 
-    public SpotArrayShadowMap(SpotLight light, TextureArray array, int firstArraySlice, int textureSize, Vector3f[] points) {
+    public SpotArrayShadowMap(SpotLight light, TextureArray array, int firstArraySlice, int textureSize) {
         super(array, firstArraySlice);
         this.light = light;
         slices = new SpotArrayShadowMapSlice[]{
-            new SpotArrayShadowMapSlice(array, firstArraySlice, textureSize, points)
+            new SpotArrayShadowMapSlice(array, firstArraySlice, textureSize)
         };
     }
 

+ 10 - 19
jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMapSlice.java

@@ -34,9 +34,10 @@ package com.jme3.shadow.next.array;
 import com.jme3.light.SpotLight;
 import com.jme3.math.FastMath;
 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.Spatial;
 import com.jme3.shadow.ShadowUtil;
 import com.jme3.texture.TextureArray;
 
@@ -45,26 +46,16 @@ import com.jme3.texture.TextureArray;
  */
 public class SpotArrayShadowMapSlice extends BaseArrayShadowMapSlice<SpotLight> {
 
-    public SpotArrayShadowMapSlice(TextureArray array, int layer, int textureSize, Vector3f[] points) {
-        super(array, layer, textureSize, points);
+    public SpotArrayShadowMapSlice(TextureArray array, int layer, int textureSize) {
+        super(array, layer, textureSize, true);
     }
 
-    public void updateShadowCamera(
-            ViewPort viewPort,
-            SpotLight light,
-            GeometryList shadowCasters) {
-
-        Camera viewCamera = viewPort.getCamera();
-        float near = viewCamera.getFrustumNear();
-        float far = viewCamera.getFrustumFar();
-
-        ShadowUtil.updateFrustumPoints(viewCamera, near, far, points);
-
-        shadowCamera.setFrustumPerspective(light.getSpotOuterAngle() * FastMath.RAD_TO_DEG * 2.0f, 1, 1, light.getSpotRange());
-        shadowCamera.lookAtDirection(light.getDirection(), shadowCamera.getUp());
+    public void updateShadowCamera(ViewPort viewPort, SpotLight light, GeometryList shadowCasters) {
         shadowCamera.setLocation(light.getPosition());
-
-        int textureSize = frameBuffer.getWidth();
-        ShadowUtil.updateShadowCamera(viewPort, null, shadowCamera, points, shadowCasters, textureSize);
+        shadowCamera.lookAtDirection(light.getDirection(), Vector3f.UNIT_Y);
+        shadowCamera.setFrustumPerspective(light.getSpotOuterAngle() * FastMath.RAD_TO_DEG * 2.0f, 1, 1, light.getSpotRange());
+        for (Spatial scene : viewPort.getScenes()) {
+            ShadowUtil.getGeometriesInCamFrustum(scene, shadowCamera, RenderQueue.ShadowMode.Cast, shadowCasters);
+        }
     }
 }