Browse Source

Pssm now supports fade out of the shadows when using a zextend

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9929 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
rem..om 13 năm trước cách đây
mục cha
commit
d1a036a021

+ 3 - 0
engine/src/core-data/Common/MatDefs/Light/Lighting.j3md

@@ -111,6 +111,7 @@ MaterialDef Phong Lighting {
         
         Float ShadowIntensity
         Vector4 Splits
+        Vector2 FadeInfo
 
         Matrix4 LightViewProjectionMatrix0
         Matrix4 LightViewProjectionMatrix1
@@ -207,6 +208,7 @@ MaterialDef Phong Lighting {
             DISCARD_ALPHA : AlphaDiscardThreshold
             COLOR_MAP : ColorMap
             SHADOWMAP_SIZE : ShadowMapSize
+            FADE : FadeInfo
         }
 
         ForcedRenderState {
@@ -232,6 +234,7 @@ MaterialDef Phong Lighting {
             DISCARD_ALPHA : AlphaDiscardThreshold
             COLOR_MAP : ColorMap
             SHADOWMAP_SIZE : ShadowMapSize
+            FADE : FadeInfo
         }
 
         ForcedRenderState {

+ 9 - 4
engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.frag

@@ -18,6 +18,10 @@ uniform mat4 m_LightViewProjectionMatrix1;
 uniform mat4 m_LightViewProjectionMatrix2;
 uniform mat4 m_LightViewProjectionMatrix3;
 
+#ifdef FADE
+uniform vec2 m_FadeInfo;
+#endif
+
 vec3 getPosition(in float depth, in vec2 uv){
     vec4 pos = vec4(uv, depth, 1.0) * 2.0 - 1.0;
     pos = m_ViewProjectionMatrixInverse * pos;
@@ -47,7 +51,7 @@ void main(){
 
     float shadowPosition = m_ViewProjectionMatrixRow2.x * worldPos.x +  m_ViewProjectionMatrixRow2.y * worldPos.y +  m_ViewProjectionMatrixRow2.z * worldPos.z +  m_ViewProjectionMatrixRow2.w;
     
-    float shadow = 0.0;
+    float shadow = 1.0;
     if(shadowPosition < m_Splits.x){
         shadow = GETSHADOW(m_ShadowMap0, projCoord0);
     }else if( shadowPosition <  m_Splits.y){
@@ -59,10 +63,11 @@ void main(){
     }else if( shadowPosition <  m_Splits.w){
         shadowBorderScale = 0.125;
         shadow = GETSHADOW(m_ShadowMap3, projCoord3);
-    }else{
-        shadow = 1.0;
     }
-    
+
+    #ifdef FADE
+      shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));    
+    #endif    
     shadow= shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
     gl_FragColor = color * vec4(shadow, shadow, shadow, 1.0);
 

+ 3 - 0
engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter.j3md

@@ -11,6 +11,7 @@ MaterialDef Post Shadow {
         
         Float ShadowIntensity
         Vector4 Splits
+        Vector2 FadeInfo
 
         Matrix4 LightViewProjectionMatrix0
         Matrix4 LightViewProjectionMatrix1
@@ -46,6 +47,7 @@ MaterialDef Post Shadow {
             FILTER_MODE : FilterMode
             PCFEDGE : PCFEdge
             SHADOWMAP_SIZE : ShadowMapSize
+            FADE : FadeInfo
         }
       
     }
@@ -63,6 +65,7 @@ MaterialDef Post Shadow {
             FILTER_MODE : FilterMode
             PCFEDGE : PCFEdge
             SHADOWMAP_SIZE : ShadowMapSize
+            FADE : FadeInfo
         }
       
     }

+ 8 - 4
engine/src/core-data/Common/MatDefs/Shadow/PostShadowFilter15.frag

@@ -20,6 +20,9 @@ uniform mat4 m_LightViewProjectionMatrix1;
 uniform mat4 m_LightViewProjectionMatrix2;
 uniform mat4 m_LightViewProjectionMatrix3;
 
+#ifdef FADE
+uniform vec2 m_FadeInfo;
+#endif
 
 vec3 getPosition(in float depth, in vec2 uv){
     vec4 pos = vec4(uv, depth, 1.0) * 2.0 - 1.0;
@@ -47,7 +50,7 @@ vec4 main_multiSample(in int numSample){
 
     float shadowPosition = m_ViewProjectionMatrixRow2.x * worldPos.x +  m_ViewProjectionMatrixRow2.y * worldPos.y +  m_ViewProjectionMatrixRow2.z * worldPos.z +  m_ViewProjectionMatrixRow2.w;
   
-float shadow = 0.0;
+    float shadow = 1.0;
     if(shadowPosition < m_Splits.x){
         shadow = GETSHADOW(m_ShadowMap0, projCoord0);
     }else if( shadowPosition <  m_Splits.y){
@@ -59,10 +62,11 @@ float shadow = 0.0;
     }else if( shadowPosition <  m_Splits.w){
         shadowBorderScale = 0.125;
         shadow = GETSHADOW(m_ShadowMap3, projCoord3);
-    }else{
-        shadow = 1.0;
     }
-    
+
+    #ifdef FADE
+      shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));    
+    #endif
     shadow= shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
   
     return color * vec4(shadow, shadow, shadow, 1.0);

+ 8 - 3
engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.frag

@@ -16,6 +16,10 @@ varying vec4 projCoord3;
     varying vec2 texCoord;
 #endif
 
+#ifdef FADE
+uniform vec2 m_FadeInfo;
+#endif
+
 void main(){   
  
     #ifdef DISCARD_ALPHA
@@ -30,7 +34,7 @@ void main(){
 
     #endif
      
-   float shadow = 0.0;
+   float shadow = 1.0;
     if(shadowPosition < m_Splits.x){
         shadow = GETSHADOW(m_ShadowMap0, projCoord0);
     }else if( shadowPosition <  m_Splits.y){
@@ -42,10 +46,11 @@ void main(){
     }else if( shadowPosition <  m_Splits.w){
         shadowBorderScale = 0.125;
         shadow = GETSHADOW(m_ShadowMap3, projCoord3);
-    }else{
-        shadow = 1.0;
     }
     
+    #ifdef FADE
+      shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));    
+    #endif
     shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
 
   gl_FragColor = vec4(shadow, shadow, shadow, 1.0);

+ 3 - 0
engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM.j3md

@@ -11,6 +11,7 @@ MaterialDef Post Shadow {
         
         Float ShadowIntensity
         Vector4 Splits
+        Vector2 FadeInfo
 
         Matrix4 LightViewProjectionMatrix0
         Matrix4 LightViewProjectionMatrix1
@@ -36,6 +37,7 @@ MaterialDef Post Shadow {
             FILTER_MODE : FilterMode
             PCFEDGE : PCFEdge
             SHADOWMAP_SIZE : ShadowMapSize
+            FADE : FadeInfo
         }
 
         RenderState {
@@ -59,6 +61,7 @@ MaterialDef Post Shadow {
             FILTER_MODE : FilterMode
             PCFEDGE : PCFEdge
             SHADOWMAP_SIZE : ShadowMapSize
+            FADE : FadeInfo
         }
 
         RenderState {

+ 15 - 10
engine/src/core-data/Common/MatDefs/Shadow/PostShadowPSSM15.frag

@@ -17,6 +17,10 @@ in vec4 projCoord3;
     varying vec2 texCoord;
 #endif
 
+#ifdef FADE
+uniform vec2 m_FadeInfo;
+#endif
+
 void main(){
     
     #ifdef DISCARD_ALPHA
@@ -32,24 +36,25 @@ void main(){
     #endif
 
     
-    float shadow = 0.0;
+    float shadow = 1.0;
     if(shadowPosition < m_Splits.x){
-        shadow = GETSHADOW(m_ShadowMap0, projCoord0);
+        shadow = GETSHADOW(m_ShadowMap0, projCoord0);   
     }else if( shadowPosition <  m_Splits.y){
         shadowBorderScale = 0.5;
-        shadow = GETSHADOW(m_ShadowMap1, projCoord1);
+        shadow = GETSHADOW(m_ShadowMap1, projCoord1);  
     }else if( shadowPosition <  m_Splits.z){
         shadowBorderScale = 0.25;
-        shadow = GETSHADOW(m_ShadowMap2, projCoord2);
+        shadow = GETSHADOW(m_ShadowMap2, projCoord2); 
     }else if( shadowPosition <  m_Splits.w){
         shadowBorderScale = 0.125;
-        shadow = GETSHADOW(m_ShadowMap3, projCoord3);
-    }else{
-        shadow = 1.0;
+        shadow = GETSHADOW(m_ShadowMap3, projCoord3); 
     }
-    
-    shadow= shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);
- 
+
+    #ifdef FADE
+      shadow = max(0.0,mix(shadow,1.0,(shadowPosition - m_FadeInfo.x) * m_FadeInfo.y));    
+    #endif
+  
+    shadow = shadow * m_ShadowIntensity + (1.0 - m_ShadowIntensity);   
     outFragColor =  vec4(shadow, shadow, shadow, 1.0);
 
 }

+ 16 - 0
engine/src/core/com/jme3/shadow/PssmShadowFilter.java

@@ -245,6 +245,22 @@ public class PssmShadowFilter extends Filter {
     final public void setFilterMode(FilterMode filterMode) {
         pssmRenderer.setFilterMode(filterMode);
     }
+    
+     /**
+     * Define the length over which the shadow will fade out when using a shadowZextend
+     * @param length the fade length in world units
+     */
+    public void setShadowZFadeLength(float length){
+       pssmRenderer.setShadowZFadeLength(length);        
+    }
+    
+     /**
+     * get the length over which the shadow will fade out when using a shadowZextend
+     * @return the fade length in world units
+     */
+    public float getShadowZFadeLength(){       
+        return pssmRenderer.getShadowZFadeLength();        
+    }
 
     @Override
     public void write(JmeExporter ex) throws IOException {

+ 48 - 1
engine/src/core/com/jme3/shadow/PssmShadowRenderer.java

@@ -35,6 +35,7 @@ import com.jme3.asset.AssetManager;
 import com.jme3.material.Material;
 import com.jme3.math.ColorRGBA;
 import com.jme3.math.Matrix4f;
+import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.post.SceneProcessor;
 import com.jme3.renderer.Camera;
@@ -162,6 +163,10 @@ public class PssmShadowRenderer implements SceneProcessor {
     private boolean applyShadowIntensity = true;
     //a list of material of the post shadow queue geometries.
     private List<Material> matCache = new ArrayList<Material>();
+    //Holding the info for fading shadows in the far distance 
+    private Vector2f fadeInfo;
+    private float fadeLength;
+    private boolean applyFadeInfo = true;
 
     /**
      * Create a PSSM Shadow Renderer 
@@ -214,7 +219,7 @@ public class PssmShadowRenderer implements SceneProcessor {
             //DO NOT COMMENT THIS (it prevent the OSX incomplete read buffer crash)
             shadowFB[i].setColorTexture(dummyTex);
 
-            postshadowMat.setTexture("ShadowMap" + i, shadowMaps[i]);
+            postshadowMat.setTexture("ShadowMap" + i, shadowMaps[i]);            
 
             //quads for debuging purpose
             dispPic[i] = new Picture("Picture" + i);
@@ -541,6 +546,11 @@ public class PssmShadowRenderer implements SceneProcessor {
                 mat.setFloat("ShadowIntensity", shadowIntensity);
                 applyShadowIntensity = false;
             }
+            
+            if (fadeInfo != null && mat.getParam("FadeInfo") == null || applyFadeInfo) {
+                mat.setVector2("FadeInfo", fadeInfo);
+                applyFadeInfo = false;
+            }
 
         }
 
@@ -604,7 +614,11 @@ public class PssmShadowRenderer implements SceneProcessor {
      * @param zFar the zFar values that override the computed one
      */
     public void setShadowZExtend(float zFar) {
+        if(fadeInfo!=null){
+            fadeInfo.set(zFar - fadeLength, 1f / fadeLength);
+        }
         this.zFarOverride = zFar;
+        
     }
 
     /**
@@ -665,4 +679,37 @@ public class PssmShadowRenderer implements SceneProcessor {
     public void setFlushQueues(boolean flushQueues) {
         this.flushQueues = flushQueues;
     }
+    
+    /**
+     * Define the length over which the shadow will fade out when using a
+     * shadowZextend
+     * This is useful to make dynamic shadows fade into baked shadows in the distance.
+     * @param length the fade length in world units
+     */
+    public void setShadowZFadeLength(float length) {
+        if (length == 0) {
+            fadeInfo = null;
+            fadeLength = 0;
+            postshadowMat.clearParam("FadeInfo");
+        } else {
+            if (zFarOverride == 0) {
+                fadeInfo = new Vector2f(0, 0);
+            } else {
+                fadeInfo = new Vector2f(zFarOverride - length, 1.0f / length);
+            }
+            fadeLength = length;
+            postshadowMat.setVector2("FadeInfo", fadeInfo);
+        }
+    }
+    
+     /**
+     * get the length over which the shadow will fade out when using a shadowZextend
+     * @return the fade length in world units
+     */
+    public float getShadowZFadeLength(){
+        if(fadeInfo!=null){
+            return zFarOverride - fadeInfo.x;
+        }
+        return 0f;        
+    }
 }