From a3145885d9265d667acedf7c032004132239767a Mon Sep 17 00:00:00 2001 From: Kirill Vainer Date: Sun, 10 Sep 2017 18:36:16 -0400 Subject: [PATCH] Support dynamic number of shadow maps --- .../logic/ShadowStaticPassLightingLogic.java | 18 ++++---- .../logic/StaticPassLightingLogic.java | 6 --- .../src/main/java/com/jme3/math/Matrix4f.java | 1 - .../main/java/com/jme3/shader/Uniform.java | 42 +++++++++++++++---- .../com/jme3/shadow/next/ShadowMapSlice.java | 12 +++++- .../next/array/BaseArrayShadowMapSlice.java | 8 ++-- .../shadow/next/array/SpotArrayShadowMap.java | 1 - .../next/array/SpotArrayShadowMapSlice.java | 2 - 8 files changed, 60 insertions(+), 30 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/material/logic/ShadowStaticPassLightingLogic.java b/jme3-core/src/main/java/com/jme3/material/logic/ShadowStaticPassLightingLogic.java index 54fad0f0f..1c6164ba1 100755 --- a/jme3-core/src/main/java/com/jme3/material/logic/ShadowStaticPassLightingLogic.java +++ b/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); diff --git a/jme3-core/src/main/java/com/jme3/material/logic/StaticPassLightingLogic.java b/jme3-core/src/main/java/com/jme3/material/logic/StaticPassLightingLogic.java index 80ff39513..7dfc0f559 100644 --- a/jme3-core/src/main/java/com/jme3/material/logic/StaticPassLightingLogic.java +++ b/jme3-core/src/main/java/com/jme3/material/logic/StaticPassLightingLogic.java @@ -75,12 +75,6 @@ public class StaticPassLightingLogic extends DefaultTechniqueDefLogic { protected final ArrayList tempPointLights = new ArrayList<>(); protected final ArrayList 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); diff --git a/jme3-core/src/main/java/com/jme3/math/Matrix4f.java b/jme3-core/src/main/java/com/jme3/math/Matrix4f.java index 159e39932..92de09332 100644 --- a/jme3-core/src/main/java/com/jme3/math/Matrix4f.java +++ b/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); diff --git a/jme3-core/src/main/java/com/jme3/shader/Uniform.java b/jme3-core/src/main/java/com/jme3/shader/Uniform.java index c377b8ebf..5475e8e2c 100644 --- a/jme3-core/src/main/java/com/jme3/shader/Uniform.java +++ b/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; } diff --git a/jme3-core/src/main/java/com/jme3/shadow/next/ShadowMapSlice.java b/jme3-core/src/main/java/com/jme3/shadow/next/ShadowMapSlice.java index bfd0cc6f7..8f5bb210c 100755 --- a/jme3-core/src/main/java/com/jme3/shadow/next/ShadowMapSlice.java +++ b/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 Type of light + * * @author Kirill Vainer */ public interface ShadowMapSlice { - 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); } diff --git a/jme3-core/src/main/java/com/jme3/shadow/next/array/BaseArrayShadowMapSlice.java b/jme3-core/src/main/java/com/jme3/shadow/next/array/BaseArrayShadowMapSlice.java index b554fb92f..a7a7ffc0a 100755 --- a/jme3-core/src/main/java/com/jme3/shadow/next/array/BaseArrayShadowMapSlice.java +++ b/jme3-core/src/main/java/com/jme3/shadow/next/array/BaseArrayShadowMapSlice.java @@ -52,6 +52,7 @@ public class BaseArrayShadowMapSlice 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 implements ArrayShadowMapS } @Override - public Matrix4f getViewProjectionMatrix() { - return shadowCamera.getViewProjectionMatrix(); + public Matrix4f getBiasedViewProjectionMatrix() { + return biasedViewProjectionMatrix; } @Override @@ -80,6 +81,7 @@ public class BaseArrayShadowMapSlice implements ArrayShadowMapS renderer.clearBuffers(false, true, false); viewPort.getQueue().renderShadowQueue(shadowCasters, renderManager, shadowCamera, true); + + BIAS_MATRIX.mult(shadowCamera.getViewProjectionMatrix(), biasedViewProjectionMatrix); } - } diff --git a/jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java b/jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java index 5046bc976..9d6d05559 100755 --- a/jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java +++ b/jme3-core/src/main/java/com/jme3/shadow/next/array/SpotArrayShadowMap.java @@ -64,5 +64,4 @@ public class SpotArrayShadowMap extends BaseArrayShadowMap {