Browse Source

Merge pull request #1932 from sebavan/Development

shadow fix pbr
David Catuhe 8 năm trước cách đây
mục cha
commit
970bd229c4

+ 1 - 5
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -305,11 +305,7 @@
 
             this._shadowMap.onClearObservable.add((engine: Engine) => {
                 if (this.useExponentialShadowMap || this.useBlurExponentialShadowMap) {
-                    if (this._useFullFloat) {
-                        engine.clear(new Color4(0, 0, 0, 0), true, true, true);
-                    } else {
-                        engine.clear(new Color4(1.0, 1.0, 1.0, 1.0), true, true, true);
-                    }
+                    engine.clear(new Color4(0, 0, 0, 0), true, true, true);
                 } else {
                     engine.clear(new Color4(1.0, 1.0, 1.0, 1.0), true, true, true);
                 }

+ 10 - 6
src/Shaders/ShadersInclude/pbrLightFunctionsCall.fx

@@ -17,20 +17,24 @@
     #endif
     
     #ifdef SHADOW{X}
-        #ifdef SHADOWVSM{X}
-            notShadowLevel = computeShadowWithVSM(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.z, shadowsInfo{X}.x);
+        #ifdef SHADOWESM{X}
+			#if defined(POINTLIGHT{X})
+				notShadowLevel = computeShadowWithESMCube(vLightData{X}.xyz, shadowSampler{X}, shadowsInfo{X}.x);
+			#else
+				notShadowLevel = computeShadowWithESM(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.x);
+			#endif
         #else
             #ifdef SHADOWPCF{X}
                 #if defined(POINTLIGHT{X})
-                    notShadowLevel = computeShadowWithPCFCube(vLightData{X}.xyz, shadowSampler{X}, shadowsInfo{X}.y, shadowsInfo{X}.z, shadowsInfo{X}.x);
+                    notShadowLevel = computeShadowWithPCFCube(vLightData{X}.xyz, shadowSampler{X}, shadowsInfo{X}.y, shadowsInfo{X}.x);
                 #else
-                    notShadowLevel = computeShadowWithPCF(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.y, shadowsInfo{X}.z, shadowsInfo{X}.x);
+                    notShadowLevel = computeShadowWithPCF(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.y, shadowsInfo{X}.x);
                 #endif
             #else
                 #if defined(POINTLIGHT{X})
-                    notShadowLevel = computeShadowCube(vLightData{X}.xyz, shadowSampler{X}, shadowsInfo{X}.x, shadowsInfo{X}.z);
+                    notShadowLevel = computeShadowCube(vLightData{X}.xyz, shadowSampler{X}, shadowsInfo{X}.x);
                 #else
-                    notShadowLevel = computeShadow(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.x, shadowsInfo{X}.z);
+                    notShadowLevel = computeShadow(vPositionFromLight{X}, shadowSampler{X}, shadowsInfo{X}.x);
                 #endif
             #endif
         #endif

+ 0 - 198
src/Shaders/ShadersInclude/pbrShadowFunctions.fx

@@ -1,198 +0,0 @@
-// Shadows
-#ifdef SHADOWS
-
-	#ifndef SHADOWFULLFLOAT
-        float unpack(vec4 color)
-        {
-            const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
-            return dot(color, bit_shift);
-        }
-    #endif
-
-    uniform vec2 depthValues;
-
-    float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
-    {
-        vec3 directionToLight = vPositionW - lightPosition;
-        float depth = length(directionToLight);
-        depth = clamp(depth, 0., 1.0);
-
-        directionToLight = normalize(directionToLight);
-        directionToLight.y = - directionToLight.y;
-
-		#ifndef SHADOWFULLFLOAT
-            float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
-        #else
-            float shadow = textureCube(shadowSampler, directionToLight).x + bias;
-        #endif
-
-        if (depth > shadow)
-        {
-            #ifdef OVERLOADEDSHADOWVALUES
-                return mix(1.0, darkness, vOverloadedShadowIntensity.x);
-            #else
-                return darkness;
-            #endif
-        }
-        return 1.0;
-    }
-
-    float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float mapSize, float bias, float darkness)
-    {
-        vec3 directionToLight = vPositionW - lightPosition;
-        float depth = length(directionToLight);
-
-        depth = (depth - depthValues.x) / (depthValues.y - depthValues.x);
-        depth = clamp(depth, 0., 1.0);
-
-        directionToLight = normalize(directionToLight);
-        directionToLight.y = -directionToLight.y;
-
-        float visibility = 1.;
-
-        vec3 poissonDisk[4];
-        poissonDisk[0] = vec3(-1.0, 1.0, -1.0);
-        poissonDisk[1] = vec3(1.0, -1.0, -1.0);
-        poissonDisk[2] = vec3(-1.0, -1.0, -1.0);
-        poissonDisk[3] = vec3(1.0, -1.0, 1.0);
-
-        // Poisson Sampling
-        float biasedDepth = depth - bias;
-
-		#ifndef SHADOWFULLFLOAT
-            if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
-            if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
-            if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
-            if (unpack(textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
-        #else
-            if (textureCube(shadowSampler, directionToLight + poissonDisk[0] * mapSize).x < biasedDepth) visibility -= 0.25;
-            if (textureCube(shadowSampler, directionToLight + poissonDisk[1] * mapSize).x < biasedDepth) visibility -= 0.25;
-            if (textureCube(shadowSampler, directionToLight + poissonDisk[2] * mapSize).x < biasedDepth) visibility -= 0.25;
-            if (textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize).x < biasedDepth) visibility -= 0.25;
-        #endif
-
-        #ifdef OVERLOADEDSHADOWVALUES
-            return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
-        #else
-            return  min(1.0, visibility + darkness);
-        #endif
-    }
-
-	float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness, float bias)
-    {
-        vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-        depth = 0.5 * depth + vec3(0.5);
-        vec2 uv = depth.xy;
-
-        if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-        {
-            return 1.0;
-        }
-
-		#ifndef SHADOWFULLFLOAT
-            float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
-        #else
-            float shadow = texture2D(shadowSampler, uv).x + bias;
-        #endif
-
-        if (depth.z > shadow)
-        {
-            #ifdef OVERLOADEDSHADOWVALUES
-                return mix(1.0, darkness, vOverloadedShadowIntensity.x);
-            #else
-                return darkness;
-            #endif
-        }
-        return 1.;
-    }
-
-    float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, float mapSize, float bias, float darkness)
-    {
-        vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-        depth = 0.5 * depth + vec3(0.5);
-        vec2 uv = depth.xy;
-
-        if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-        {
-            return 1.0;
-        }
-
-        float visibility = 1.;
-
-        vec2 poissonDisk[4];
-        poissonDisk[0] = vec2(-0.94201624, -0.39906216);
-        poissonDisk[1] = vec2(0.94558609, -0.76890725);
-        poissonDisk[2] = vec2(-0.094184101, -0.92938870);
-        poissonDisk[3] = vec2(0.34495938, 0.29387760);
-
-        // Poisson Sampling
-        float biasedDepth = depth.z - bias;
-
-		#ifndef SHADOWFULLFLOAT
-            if (unpack(texture2D(shadowSampler, uv + poissonDisk[0] * mapSize)) < biasedDepth) visibility -= 0.25;
-            if (unpack(texture2D(shadowSampler, uv + poissonDisk[1] * mapSize)) < biasedDepth) visibility -= 0.25;
-            if (unpack(texture2D(shadowSampler, uv + poissonDisk[2] * mapSize)) < biasedDepth) visibility -= 0.25;
-            if (unpack(texture2D(shadowSampler, uv + poissonDisk[3] * mapSize)) < biasedDepth) visibility -= 0.25;
-        #else
-            if (texture2D(shadowSampler, uv + poissonDisk[0] * mapSize).x < biasedDepth) visibility -= 0.25;
-            if (texture2D(shadowSampler, uv + poissonDisk[1] * mapSize).x < biasedDepth) visibility -= 0.25;
-            if (texture2D(shadowSampler, uv + poissonDisk[2] * mapSize).x < biasedDepth) visibility -= 0.25;
-            if (texture2D(shadowSampler, uv + poissonDisk[3] * mapSize).x < biasedDepth) visibility -= 0.25;
-        #endif
-
-        #ifdef OVERLOADEDSHADOWVALUES
-            return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
-        #else
-            return  min(1.0, visibility + darkness);
-        #endif
-    }
-
-	#ifndef SHADOWFULLFLOAT
-        // Thanks to http://devmaster.net/
-        float unpackHalf(vec2 color)
-        {
-            return color.x + (color.y / 255.0);
-        }
-    #endif
-
-    float linstep(float low, float high, float v) {
-        return clamp((v - low) / (high - low), 0.0, 1.0);
-    }
-
-    float ChebychevInequality(vec2 moments, float compare, float bias)
-    {
-        float p = smoothstep(compare - bias, compare, moments.x);
-        float variance = max(moments.y - moments.x * moments.x, 0.02);
-        float d = compare - moments.x;
-        float p_max = linstep(0.2, 1.0, variance / (variance + d * d));
-
-        return clamp(max(p, p_max), 0.0, 1.0);
-    }
-
-    float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias, float darkness)
-    {
-        vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-        depth = 0.5 * depth + vec3(0.5);
-        vec2 uv = depth.xy;
-
-        if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0 || depth.z >= 1.0)
-        {
-            return 1.0;
-        }
-
-        vec4 texel = texture2D(shadowSampler, uv);
-
-        #ifndef SHADOWFULLFLOAT
-            vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-        #else
-            vec2 moments = texel.xy;
-        #endif
-
-        #ifdef OVERLOADEDSHADOWVALUES
-            return min(1.0, mix(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness, vOverloadedShadowIntensity.x));
-        #else
-            return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
-        #endif
-    }
-
-#endif

+ 36 - 11
src/Shaders/ShadersInclude/shadowsFragmentFunctions.fx

@@ -27,7 +27,11 @@
 
 		if (depth > shadow)
 		{
-			return darkness;
+			#ifdef OVERLOADEDSHADOWVALUES
+                return mix(1.0, darkness, vOverloadedShadowIntensity.x);
+            #else
+                return darkness;
+            #endif
 		}
 		return 1.0;
 	}
@@ -65,7 +69,11 @@
 			if (textureCube(shadowSampler, directionToLight + poissonDisk[3] * mapSize).x < depth) visibility -= 0.25;
 		#endif
 
-		return  min(1.0, visibility + darkness);
+		#ifdef OVERLOADEDSHADOWVALUES
+            return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
+        #else
+            return  min(1.0, visibility + darkness);
+        #endif
 	}
 
 	float computeShadowWithESMCube(vec3 lightPosition, samplerCube shadowSampler, float darkness)
@@ -84,8 +92,13 @@
 			float shadowMapSample = textureCube(shadowSampler, directionToLight).x;
 		#endif
 
-		const float shadowStrength = 30.;
-		return 1.0 - clamp(exp(-shadowStrength * shadowPixelDepth) * shadowMapSample - darkness, 0., 1.);
+		const float shadowStrength = 80.;
+		float visibility = 1.0 - clamp(exp(shadowStrength * shadowPixelDepth) * shadowMapSample - darkness, 0., 1.);
+		#ifdef OVERLOADEDSHADOWVALUES
+			return mix(1.0, visibility, vOverloadedShadowIntensity.x);
+		#else
+			return visibility;
+		#endif
 	}
 
 	float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness)
@@ -107,7 +120,11 @@
 
 		if (depth.z > shadow)
 		{
-			return darkness;
+			#ifdef OVERLOADEDSHADOWVALUES
+                return mix(1.0, darkness, vOverloadedShadowIntensity.x);
+            #else
+                return darkness;
+            #endif
 		}
 		return 1.;
 	}
@@ -144,8 +161,12 @@
 			if (texture2D(shadowSampler, uv + poissonDisk[2] * mapSize).x < depth.z) visibility -= 0.25;
 			if (texture2D(shadowSampler, uv + poissonDisk[3] * mapSize).x < depth.z) visibility -= 0.25;
 		#endif
-
-		return  min(1.0, visibility + darkness);
+		
+        #ifdef OVERLOADEDSHADOWVALUES
+            return  mix(1.0, min(1.0, visibility + darkness), vOverloadedShadowIntensity.x);
+        #else
+            return  min(1.0, visibility + darkness);
+        #endif
 	}
 
 	float computeShadowWithESM(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness)
@@ -163,19 +184,23 @@
 		const float shadowStrength = 80.;
 		#ifndef SHADOWFULLFLOAT
 			float shadowMapSample = unpack(texture2D(shadowSampler, uv));
-			float esm = clamp(exp(-shadowStrength * shadowPixelDepth) * shadowMapSample - darkness, 0., 1.);
 		#else
 			float shadowMapSample = texture2D(shadowSampler, uv).x;
-			float esm = 1.0 - clamp(exp(shadowStrength * shadowPixelDepth) * shadowMapSample - darkness, 0., 1.);
 		#endif
+		
+		float esm = 1.0 - clamp(exp(shadowStrength * shadowPixelDepth) * shadowMapSample - darkness, 0., 1.);
 
 		// Apply fade out at frustum edge
 		// const float fadeDistance = 0.07;
 		// vec2 cs2 = clipSpace.xy * clipSpace.xy; //squarish falloff
 		// float mask = smoothstep(1.0, 1.0 - fadeDistance, dot(cs2, cs2));
 
-		// return mix(1.0, esm, mask);
+		// esm = mix(1.0, esm, mask);
 
-		return esm;
+		#ifdef OVERLOADEDSHADOWVALUES
+            return mix(1.0, esm, vOverloadedShadowIntensity.x);
+        #else
+            return esm;
+        #endif
 	}
 #endif

+ 1 - 1
src/Shaders/pbr.fragment.fx

@@ -157,7 +157,7 @@ uniform mat4 reflectionMatrix;
 #endif
 
 // PBR
-#include<pbrShadowFunctions>
+#include<shadowsFragmentFunctions>
 #include<pbrFunctions>
 
 #ifdef CAMERACOLORGRADING