Browse Source

Support dynamic number of shadow maps

Kirill Vainer 8 năm trước cách đây
mục cha
commit
a3145885d9

+ 10 - 8
jme3-core/src/main/java/com/jme3/material/logic/ShadowStaticPassLightingLogic.java

@@ -69,7 +69,6 @@ public class ShadowStaticPassLightingLogic extends StaticPassLightingLogic {
     private int numShadowDirLights = 0;
     private int numShadowPointLights = 0;
     private int numShadowSpotLights = 0;
-    private final Matrix4f[] shadowMatrices = new Matrix4f[5];
 
     public ShadowStaticPassLightingLogic(TechniqueDef techniqueDef) {
         super(techniqueDef);
@@ -77,10 +76,6 @@ public class ShadowStaticPassLightingLogic extends StaticPassLightingLogic {
         numShadowDirLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_SHADOW_DIR_LIGHTS, VarType.Int);
         numShadowPointLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_SHADOW_POINT_LIGHTS, VarType.Int);
         numShadowSpotLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_SHADOW_SPOT_LIGHTS, VarType.Int);
-
-        for (int i = 0; i < shadowMatrices.length; i++) {
-            shadowMatrices[i] = new Matrix4f();
-        }
     }
 
     @Override
@@ -157,6 +152,9 @@ public class ShadowStaticPassLightingLogic extends StaticPassLightingLogic {
         Vector4f pssmSplits = null;
 
         Uniform shadowMatricesUniform = shader.getUniform("g_ShadowMatrices");
+        
+        shadowMatricesUniform.setMatrix4Length(numShadowDirLights * 4 + numShadowSpotLights);
+
         int shadowMatrixIndex = 0;
         for (int i = 0; i < numShadowDirLights; i++) {
             DirectionalArrayShadowMap map = (DirectionalArrayShadowMap) tempDirLights.get(i).getShadowMap();
@@ -164,7 +162,9 @@ public class ShadowStaticPassLightingLogic extends StaticPassLightingLogic {
             pssmSplits = map.getProjectionSplitPositions();
             for (int j = 0; j < map.getNumSlices(); j++) {
                 ArrayShadowMapSlice slice = (ArrayShadowMapSlice) map.getSlice(j);
-                BIAS_MATRIX.mult(slice.getViewProjectionMatrix(), shadowMatrices[shadowMatrixIndex]);
+                shadowMatricesUniform.setMatrix4InArray(
+                        slice.getBiasedViewProjectionMatrix(),
+                        shadowMatrixIndex);
                 shadowMatrixIndex++;
             }
         }
@@ -173,16 +173,18 @@ public class ShadowStaticPassLightingLogic extends StaticPassLightingLogic {
             SpotArrayShadowMap map = (SpotArrayShadowMap) tempSpotLights.get(i).getShadowMap();
             array = map.getArray();
             SpotArrayShadowMapSlice slice = map.getSlice(0);
-            BIAS_MATRIX.mult(slice.getViewProjectionMatrix(), shadowMatrices[shadowMatrixIndex]);
+            shadowMatricesUniform.setMatrix4InArray(
+                        slice.getBiasedViewProjectionMatrix(),
+                        shadowMatrixIndex);
             shadowMatrixIndex++;
         }
 
-        shadowMatricesUniform.setValue(VarType.Matrix4Array, shadowMatrices);
         if (array != null) {
             renderer.setTexture(nextTextureUnit, array);
             Uniform shadowMapArrayUniform = shader.getUniform("g_ShadowMapArray");
             shadowMapArrayUniform.setValue(VarType.Int, nextTextureUnit);
         }
+        
         if (pssmSplits != null) {
             Uniform pssmSplitsUniform = shader.getUniform("g_PssmSplits");
             pssmSplitsUniform.setValue(VarType.Vector4, pssmSplits);

+ 0 - 6
jme3-core/src/main/java/com/jme3/material/logic/StaticPassLightingLogic.java

@@ -75,12 +75,6 @@ public class StaticPassLightingLogic extends DefaultTechniqueDefLogic {
     protected final ArrayList<PointLight> tempPointLights = new ArrayList<>();
     protected final ArrayList<SpotLight> tempSpotLights = new ArrayList<>();
 
-    protected static final Matrix4f BIAS_MATRIX = new Matrix4f(
-            0.5f, 0.0f, 0.0f, 0.5f,
-            0.0f, 0.5f, 0.0f, 0.5f,
-            0.0f, 0.0f, 0.5f, 0.5f,
-            0.0f, 0.0f, 0.0f, 1.0f);
-
     public StaticPassLightingLogic(TechniqueDef techniqueDef) {
         super(techniqueDef);
 

+ 0 - 1
jme3-core/src/main/java/com/jme3/math/Matrix4f.java

@@ -752,7 +752,6 @@ public final class Matrix4f implements Savable, Cloneable, java.io.Serializable
 
         TempVars vars = TempVars.get();
 
-
         fillFloatArray(vars.matrixWrite, columnMajor);
         fb.put(vars.matrixWrite, 0, 16);
 

+ 35 - 7
jme3-core/src/main/java/com/jme3/shader/Uniform.java

@@ -197,7 +197,7 @@ public class Uniform extends ShaderVariable {
         }
     }
     
-    public void setValue(VarType type, Object value){
+    public void setValue(VarType type, Object value) {
         if (location == LOC_NOT_DEFINED) {
             return;
         }
@@ -386,12 +386,40 @@ public class Uniform extends ShaderVariable {
         varType = type;
         updateNeeded = true;
     }
+    
+    public void setMatrix4Length(int length) {
+        if (location == LOC_NOT_DEFINED) {
+            return;
+        }
+
+        multiData = BufferUtils.ensureLargeEnough(multiData, length * 4 * 4);
+        value = multiData;
+        varType = VarType.Matrix4Array;
+        updateNeeded = true;
+        setByCurrentMaterial = true;
+    }
+    
+    public void setMatrix4InArray(Matrix4f matrix, int index) {
+        if (location == LOC_NOT_DEFINED) {
+            return;
+        }
 
-    public void setVector4Length(int length){
-        if (location == -1) {
+        if (varType != null && varType != VarType.Matrix4Array) {
+            throw new IllegalArgumentException("Expected a " + varType.name() + " value!");
+        }
+
+        multiData.position(index * 4 * 4);
+        matrix.fillFloatBuffer(multiData, true);
+        multiData.rewind();
+        updateNeeded = true;
+        setByCurrentMaterial = true;
+    }
+
+    public void setVector4Length(int length) {
+        if (location == LOC_NOT_DEFINED) {
             return;
         }
-        
+
         multiData = BufferUtils.ensureLargeEnough(multiData, length * 4);
         value = multiData;
         varType = VarType.Vector4Array;
@@ -399,8 +427,8 @@ public class Uniform extends ShaderVariable {
         setByCurrentMaterial = true;
     }
 
-    public void setVector4InArray(float x, float y, float z, float w, int index){
-        if (location == -1) {
+    public void setVector4InArray(float x, float y, float z, float w, int index) {
+        if (location == LOC_NOT_DEFINED) {
             return;
         }
 
@@ -414,7 +442,7 @@ public class Uniform extends ShaderVariable {
         updateNeeded = true;
         setByCurrentMaterial = true;
     }
-    
+
     public boolean isUpdateNeeded(){
         return updateNeeded;
     }

+ 10 - 2
jme3-core/src/main/java/com/jme3/shadow/next/ShadowMapSlice.java

@@ -39,12 +39,20 @@ import com.jme3.renderer.queue.GeometryList;
 
 /**
  * Represents a single slice of a shadow map.
- *
+ * 
+ * @param <T> Type of light
+ * 
  * @author Kirill Vainer
  */
 public interface ShadowMapSlice<T extends Light> {
 
-    public Matrix4f getViewProjectionMatrix();
+    public static final Matrix4f BIAS_MATRIX = new Matrix4f(
+            0.5f, 0.0f, 0.0f, 0.5f,
+            0.0f, 0.5f, 0.0f, 0.5f,
+            0.0f, 0.0f, 0.5f, 0.5f,
+            0.0f, 0.0f, 0.0f, 1.0f);
+
+    public Matrix4f getBiasedViewProjectionMatrix();
 
     public void renderShadowMap(RenderManager renderManager, T light, ViewPort viewPort, GeometryList shadowCasters);
 }

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

@@ -52,6 +52,7 @@ 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) {
         this.shadowCamera = new Camera(textureSize, textureSize);
@@ -67,8 +68,8 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
     }
 
     @Override
-    public Matrix4f getViewProjectionMatrix() {
-        return shadowCamera.getViewProjectionMatrix();
+    public Matrix4f getBiasedViewProjectionMatrix() {
+        return biasedViewProjectionMatrix;
     }
 
     @Override
@@ -80,6 +81,7 @@ public class BaseArrayShadowMapSlice<T extends Light> implements ArrayShadowMapS
         renderer.clearBuffers(false, true, false);
 
         viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true);
+        
+        BIAS_MATRIX.mult(shadowCamera.getViewProjectionMatrix(), biasedViewProjectionMatrix);
     }
-
 }

+ 0 - 1
jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java

@@ -64,5 +64,4 @@ public class SpotArrayShadowMap extends BaseArrayShadowMap<SpotArrayShadowMapSli
     public Light.Type getLightType() {
         return Light.Type.Spot;
     }
-
 }

+ 0 - 2
jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMapSlice.java

@@ -33,7 +33,6 @@ package com.jme3.shadow.next.array;
 
 import com.jme3.light.SpotLight;
 import com.jme3.math.FastMath;
-import com.jme3.math.Matrix4f;
 import com.jme3.math.Vector3f;
 import com.jme3.renderer.Camera;
 import com.jme3.renderer.ViewPort;
@@ -42,7 +41,6 @@ import com.jme3.shadow.ShadowUtil;
 import com.jme3.texture.TextureArray;
 
 /**
- *
  * @author Kirill Vainer
  */
 public class SpotArrayShadowMapSlice extends BaseArrayShadowMapSlice<SpotLight> {