Browse Source

add point light mode for pre shadow techniques

Kirill Vainer 8 years ago
parent
commit
e4536808ca

+ 8 - 0
jme3-core/src/main/java/com/jme3/shadow/next/PreShadowArrayRenderer.java

@@ -34,8 +34,10 @@ package com.jme3.shadow.next;
 import com.jme3.shadow.next.pssm.DirectionalShadowParameters;
 import com.jme3.light.DirectionalLight;
 import com.jme3.light.Light;
+import com.jme3.light.Light.Type;
 import com.jme3.light.PointLight;
 import com.jme3.light.SpotLight;
+import com.jme3.material.MatParamOverride;
 import com.jme3.material.RenderState;
 import com.jme3.math.Vector3f;
 import com.jme3.post.SceneProcessor;
@@ -46,6 +48,7 @@ import com.jme3.renderer.ViewPort;
 import com.jme3.renderer.queue.GeometryList;
 import com.jme3.renderer.queue.OpaqueComparator;
 import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.shader.VarType;
 import com.jme3.shadow.next.array.DirectionalArrayShadowMap;
 import com.jme3.shadow.next.array.PointArrayShadowMap;
 import com.jme3.shadow.next.array.SpotArrayShadowMap;
@@ -80,6 +83,7 @@ public class PreShadowArrayRenderer implements SceneProcessor {
     private final GeometryList shadowCasters = new GeometryList(new OpaqueComparator());
     private final ListMap<Light, ShadowMap> shadowedLights = new ListMap<>();
     private final RenderState prePassRenderState = RenderState.ADDITIONAL.clone();
+    private final MatParamOverride pointLightOverride = new MatParamOverride(VarType.Boolean, "IsPointLight", true);
     private final TextureArray array = new TextureArray();
     
     private int textureSize = 1024;
@@ -190,6 +194,7 @@ public class PreShadowArrayRenderer implements SceneProcessor {
     private void renderShadowMaps(ViewPort viewPort) {
         renderManager.setForcedRenderState(prePassRenderState);
         renderManager.setForcedTechnique(PRE_SHADOW_TECHNIQUE_NAME);
+        renderManager.addForcedMatParam(pointLightOverride);
 
         for (int i = 0; i < shadowedLights.size(); i++) {
             Light light = shadowedLights.getKey(i);
@@ -206,6 +211,8 @@ public class PreShadowArrayRenderer implements SceneProcessor {
                 vars.release();
             }
 
+            pointLightOverride.setEnabled(shadowMap.getLightType() == Type.Point);
+            
             switch (shadowMap.getLightType()) {
                 case Directional:
                     DirectionalArrayShadowMap directionalShadow = (DirectionalArrayShadowMap) shadowMap;
@@ -228,6 +235,7 @@ public class PreShadowArrayRenderer implements SceneProcessor {
 
         Renderer renderer = renderManager.getRenderer();
         renderer.setFrameBuffer(viewPort.getOutputFrameBuffer());
+        renderManager.removeForcedMatParam(pointLightOverride);
         renderManager.setForcedRenderState(null);
         renderManager.setForcedTechnique(null);
         renderManager.setCamera(viewPort.getCamera(), false);

+ 7 - 0
jme3-core/src/main/resources/Common/MatDefs/Light/Lighting.j3md

@@ -118,6 +118,9 @@ MaterialDef Phong Lighting {
         Boolean UseInstancing
 
         Boolean BackfaceShadows : false
+
+        // PreShadow: use point light mode for depth
+        Boolean IsPointLight
     }
 
     Technique {
@@ -228,12 +231,16 @@ MaterialDef Phong Lighting {
             WorldViewMatrix
             ViewProjectionMatrix
             ViewMatrix
+            WorldMatrix
+            CameraPosition
+            FrustumNearFar
         }
 
         Defines {
             DISCARD_ALPHA : AlphaDiscardThreshold
             NUM_BONES : NumberOfBones
             INSTANCING : UseInstancing
+            POINT_LIGHT : IsPointLight
         }
 
         ForcedRenderState {

+ 7 - 0
jme3-core/src/main/resources/Common/MatDefs/Light/PBRLighting.j3md

@@ -118,6 +118,9 @@ MaterialDef PBR Lighting {
         Boolean UseVertexColor
 
         Boolean BackfaceShadows : false
+
+        // PreShadow: use point light mode for depth
+        Boolean IsPointLight
     }
 
     Technique {
@@ -171,12 +174,16 @@ MaterialDef PBR Lighting {
             WorldViewMatrix
             ViewProjectionMatrix
             ViewMatrix
+            WorldMatrix
+            CameraPosition
+            FrustumNearFar
         }
 
         Defines {
             DISCARD_ALPHA : AlphaDiscardThreshold
             NUM_BONES : NumberOfBones
             INSTANCING : UseInstancing
+            POINT_LIGHT : IsPointLight
         }
 
         ForcedRenderState {

+ 7 - 0
jme3-core/src/main/resources/Common/MatDefs/Misc/Particle.j3md

@@ -14,6 +14,9 @@ MaterialDef Point Sprite {
         Texture2D GlowMap
         // The glow color of the object
         Color GlowColor
+
+        // PreShadow: use point light mode for depth
+        Boolean IsPointLight
     }
 
     Technique {
@@ -56,10 +59,14 @@ MaterialDef Point Sprite {
             WorldViewMatrix
             ViewProjectionMatrix
             ViewMatrix
+            WorldMatrix
+            CameraPosition
+            FrustumNearFar
         }
 
         Defines {
             COLOR_MAP : Texture
+            POINT_LIGHT : IsPointLight
         }
 
         ForcedRenderState {

+ 7 - 0
jme3-core/src/main/resources/Common/MatDefs/Misc/Unshaded.j3md

@@ -54,6 +54,9 @@ MaterialDef Unshaded {
         Float ShadowMapSize
 
         Boolean BackfaceShadows: true
+
+        // PreShadow: use point light mode for depth
+        Boolean IsPointLight
     }
 
     Technique {
@@ -108,6 +111,9 @@ MaterialDef Unshaded {
             WorldViewMatrix
             ViewProjectionMatrix
             ViewMatrix
+            WorldMatrix
+            CameraPosition
+            FrustumNearFar
         }
 
         Defines {
@@ -115,6 +121,7 @@ MaterialDef Unshaded {
             DISCARD_ALPHA : AlphaDiscardThreshold
             NUM_BONES : NumberOfBones
             INSTANCING : UseInstancing
+            POINT_LIGHT : IsPointLight
         }
 
         ForcedRenderState {

+ 13 - 0
jme3-core/src/main/resources/Common/MatDefs/Shadow/PreShadow.j3md

@@ -1,11 +1,24 @@
 MaterialDef Pre Shadow {
+
+    MaterialParameters {
+        // PreShadow: use point light mode for depth
+        Boolean IsPointLight
+    }
+
     Technique {
         VertexShader GLSL100 GLSL150 :   Common/MatDefs/Shadow/PreShadow.vert
         FragmentShader GLSL100 GLSL150 : Common/MatDefs/Shadow/PreShadow.frag
 
+        Defines {
+            POINT_LIGHT : IsPointLight
+        }
+
         WorldParameters {
             WorldViewProjectionMatrix
             WorldViewMatrix
+            WorldMatrix
+            CameraPosition
+            FrustumNearFar
         }
 
         RenderState {

+ 26 - 6
jme3-core/src/main/resources/Common/MatDefs/Shadow/PreShadow.vert

@@ -2,16 +2,36 @@
 #import "Common/ShaderLib/Instancing.glsllib"
 #import "Common/ShaderLib/Skinning.glsllib"
 attribute vec3 inPosition;
+#ifdef DISCARD_ALPHA
 attribute vec2 inTexCoord;
-
 varying vec2 texCoord;
+#endif
+
+#ifdef POINT_LIGHT
+uniform vec3 g_CameraPosition;
+uniform vec2 g_FrustumNearFar;
+#endif
 
-void main(){
+void main() {
     vec4 modelSpacePos = vec4(inPosition, 1.0);
   
-   #ifdef NUM_BONES
-       Skinning_Compute(modelSpacePos);
-   #endif
+    #ifdef NUM_BONES
+        Skinning_Compute(modelSpacePos);
+    #endif
+
+    #ifdef DISCARD_ALPHA
+        texCoord = inTexCoord;
+    #endif
+
     gl_Position = TransformWorldViewProjection(modelSpacePos);
-    texCoord = inTexCoord;
+
+    #ifdef POINT_LIGHT
+        vec3 lightDir = g_CameraPosition - TransformWorld(modelSpacePos).xyz;
+
+        // The Z value to write into the depth map, should be [0.0, 1.0]
+        float z = length(lightDir) / g_FrustumNearFar.y;
+
+        // Remap [0.0, 1.0] into [-1.0, 1.0]
+        gl_Position.z = (clamp(z, 0.0, 1.0) * 2.0 - 1.0) * gl_Position.w;
+    #endif
 }