Selaa lähdekoodia

Fixed issue with multiple shadows

David Catuhe 9 vuotta sitten
vanhempi
commit
dc58d0cb14

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 25 - 25
dist/preview release/babylon.core.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1515 - 1515
dist/preview release/babylon.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 3
dist/preview release/babylon.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/babylon.max.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 20 - 20
dist/preview release/babylon.noworker.js


+ 124 - 128
src/Shaders/ShadersInclude/pbrShadowFunctions.fx

@@ -7,165 +7,161 @@
         return dot(color, bit_shift);
     }
 
-    #if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
-        uniform vec2 depthValues;
+    uniform vec2 depthValues;
 
-        float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
+    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;
+
+        float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+
+        if (depth > shadow)
         {
-            vec3 directionToLight = vPositionW - lightPosition;
-            float depth = length(directionToLight);
-            depth = clamp(depth, 0., 1.0);
-
-            directionToLight = normalize(directionToLight);
-            directionToLight.y = - directionToLight.y;
-
-            float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
-
-            if (depth > shadow)
-            {
-                #ifdef OVERLOADEDSHADOWVALUES
-                    return mix(1.0, darkness, vOverloadedShadowIntensity.x);
-                #else
-                    return darkness;
-                #endif
-            }
-            return 1.0;
+            #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);
+    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;
 
-            depth = (depth - depthValues.x) / (depthValues.y - depthValues.x);
-            depth = clamp(depth, 0., 1.0);
+        float visibility = 1.;
 
-            directionToLight = normalize(directionToLight);
-            directionToLight.y = -directionToLight.y;
+        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);
 
-            float visibility = 1.;
+        // Poisson Sampling
+        float biasedDepth = depth - bias;
 
-            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);
+        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;
 
-            // Poisson Sampling
-            float biasedDepth = depth - bias;
+        #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;
+        }
 
-            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;
+        float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
 
+        if (depth.z > shadow)
+        {
             #ifdef OVERLOADEDSHADOWVALUES
-                return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
+                return mix(1.0, darkness, vOverloadedShadowIntensity.x);
             #else
-                return  min(1.0, visibility + darkness);
+                return darkness;
             #endif
         }
-    #endif
+        return 1.;
+    }
 
-    #if defined(SPOTLIGHT0) || defined(SPOTLIGHT1) || defined(SPOTLIGHT2) || defined(SPOTLIGHT3) ||  defined(DIRLIGHT0) || defined(DIRLIGHT1) || defined(DIRLIGHT2) || defined(DIRLIGHT3)
-        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;
-            }
-
-            float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
-
-            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;
 
-        float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, float mapSize, float bias, float darkness)
+        if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
         {
-            vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-            depth = 0.5 * depth + vec3(0.5);
-            vec2 uv = depth.xy;
+            return 1.0;
+        }
 
-            if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-            {
-                return 1.0;
-            }
+        float visibility = 1.;
 
-            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);
 
-            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;
 
-            // Poisson Sampling
-            float biasedDepth = depth.z - bias;
+        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;
 
-            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;
+        #ifdef OVERLOADEDSHADOWVALUES
+            return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
+        #else
+            return  min(1.0, visibility + darkness);
+        #endif
+    }
 
-            #ifdef OVERLOADEDSHADOWVALUES
-                return  min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
-            #else
-                return  min(1.0, visibility + darkness);
-            #endif
-        }
+    // Thanks to http://devmaster.net/
+    float unpackHalf(vec2 color)
+    {
+        return color.x + (color.y / 255.0);
+    }
 
-        // Thanks to http://devmaster.net/
-        float unpackHalf(vec2 color)
-        {
-            return color.x + (color.y / 255.0);
-        }
+    float linstep(float low, float high, float v) {
+        return clamp((v - low) / (high - low), 0.0, 1.0);
+    }
 
-        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));
 
-        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);
+    }
 
-            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;
 
-        float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias, float darkness)
+        if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0 || depth.z >= 1.0)
         {
-            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;
-            }
+            return 1.0;
+        }
 
-            vec4 texel = texture2D(shadowSampler, uv);
+        vec4 texel = texture2D(shadowSampler, uv);
 
-            vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-            #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
+        vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
+        #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

+ 104 - 108
src/Shaders/ShadersInclude/shadowsFragmentFunctions.fx

@@ -5,145 +5,141 @@
 		return dot(color, bit_shift);
 	}
 
-	#if defined(POINTLIGHT0) || defined(POINTLIGHT1) || defined(POINTLIGHT2) || defined(POINTLIGHT3)
-		uniform vec2 depthValues;
+	uniform vec2 depthValues;
 
-		float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
-		{
-			vec3 directionToLight = vPositionW - lightPosition;
-			float depth = length(directionToLight);
-			depth = (depth - depthValues.x) / (depthValues.y - depthValues.x);
-			depth = clamp(depth, 0., 1.0);
+	float computeShadowCube(vec3 lightPosition, samplerCube shadowSampler, float darkness, float bias)
+	{
+		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;
+		directionToLight = normalize(directionToLight);
+		directionToLight.y = -directionToLight.y;
 
-			float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
+		float shadow = unpack(textureCube(shadowSampler, directionToLight)) + bias;
 
-			if (depth > shadow)
-			{
-				return darkness;
-			}
-			return 1.0;
+		if (depth > shadow)
+		{
+			return darkness;
 		}
+		return 1.0;
+	}
 
-		float computeShadowWithPCFCube(vec3 lightPosition, samplerCube shadowSampler, float mapSize, float bias, float darkness)
-		{
-			vec3 directionToLight = vPositionW - lightPosition;
-			float depth = length(directionToLight);
+	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);
+		depth = (depth - depthValues.x) / (depthValues.y - depthValues.x);
+		depth = clamp(depth, 0., 1.0);
 
-			directionToLight = normalize(directionToLight);
-			directionToLight.y = -directionToLight.y;
+		directionToLight = normalize(directionToLight);
+		directionToLight.y = -directionToLight.y;
 
-			float visibility = 1.;
+		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);
+		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;
+		// Poisson Sampling
+		float biasedDepth = depth - bias;
 
-			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;
+		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;
 
-			return  min(1.0, visibility + darkness);
+		return  min(1.0, visibility + darkness);
+	}
+
+	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;
 		}
-	#endif
 
-	#if defined(SPOTLIGHT0) || defined(SPOTLIGHT1) || defined(SPOTLIGHT2) || defined(SPOTLIGHT3) ||  defined(DIRLIGHT0) || defined(DIRLIGHT1) || defined(DIRLIGHT2) || defined(DIRLIGHT3)
-		float computeShadow(vec4 vPositionFromLight, sampler2D shadowSampler, float darkness, float bias)
+		float shadow = unpack(texture2D(shadowSampler, uv)) + bias;
+
+		if (depth.z > shadow)
 		{
-			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 shadow = unpack(texture2D(shadowSampler, uv)) + bias;
-
-			if (depth.z > shadow)
-			{
-				return darkness;
-			}
-			return 1.;
+			return darkness;
 		}
+		return 1.;
+	}
 
-		float computeShadowWithPCF(vec4 vPositionFromLight, sampler2D shadowSampler, float mapSize, float bias, float darkness)
+	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)
 		{
-			vec3 depth = vPositionFromLight.xyz / vPositionFromLight.w;
-			depth = 0.5 * depth + vec3(0.5);
-			vec2 uv = depth.xy;
+			return 1.0;
+		}
 
-			if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0)
-			{
-				return 1.0;
-			}
+		float visibility = 1.;
 
-			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);
 
-			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;
 
-			// Poisson Sampling
-			float biasedDepth = depth.z - bias;
+		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;
 
-			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;
+		return  min(1.0, visibility + darkness);
+	}
 
-			return  min(1.0, visibility + darkness);
-		}
+	// Thanks to http://devmaster.net/
+	float unpackHalf(vec2 color)
+	{
+		return color.x + (color.y / 255.0);
+	}
 
-		// Thanks to http://devmaster.net/
-		float unpackHalf(vec2 color)
-		{
-			return color.x + (color.y / 255.0);
-		}
+	float linstep(float low, float high, float v) {
+		return clamp((v - low) / (high - low), 0.0, 1.0);
+	}
 
-		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));
 
-		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);
+	}
 
-			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;
 
-		float computeShadowWithVSM(vec4 vPositionFromLight, sampler2D shadowSampler, float bias, float darkness)
+		if (uv.x < 0. || uv.x > 1.0 || uv.y < 0. || uv.y > 1.0 || depth.z >= 1.0)
 		{
-			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;
-			}
+			return 1.0;
+		}
 
-			vec4 texel = texture2D(shadowSampler, uv);
+		vec4 texel = texture2D(shadowSampler, uv);
 
-			vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
-			return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
-		}
-	#endif
+		vec2 moments = vec2(unpackHalf(texel.xy), unpackHalf(texel.zw));
+		return min(1.0, 1.0 - ChebychevInequality(moments, depth.z, bias) + darkness);
+	}
 #endif

+ 2 - 11
src/Shaders/ShadersInclude/shadowsVertex.fx

@@ -1,14 +1,5 @@
 #ifdef SHADOWS
-	#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-		vPositionFromLight0 = lightMatrix0 * worldPos;
-	#endif
-	#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-		vPositionFromLight1 = lightMatrix1 * worldPos;
-	#endif
-	#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-		vPositionFromLight2 = lightMatrix2 * worldPos;
-	#endif
-	#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-		vPositionFromLight3 = lightMatrix3 * worldPos;
+	#if defined(SPOTLIGHT{X}) || defined(DIRLIGHT{X})
+		vPositionFromLight{X} = lightMatrix{X} * worldPos;
 	#endif
 #endif

+ 3 - 15
src/Shaders/ShadersInclude/shadowsVertexDeclaration.fx

@@ -1,18 +1,6 @@
 #ifdef SHADOWS
-	#if defined(SPOTLIGHT0) || defined(DIRLIGHT0)
-		uniform mat4 lightMatrix0;
-		varying vec4 vPositionFromLight0;
-	#endif
-	#if defined(SPOTLIGHT1) || defined(DIRLIGHT1)
-		uniform mat4 lightMatrix1;
-		varying vec4 vPositionFromLight1;
-	#endif
-	#if defined(SPOTLIGHT2) || defined(DIRLIGHT2)
-		uniform mat4 lightMatrix2;
-		varying vec4 vPositionFromLight2;
-	#endif
-	#if defined(SPOTLIGHT3) || defined(DIRLIGHT3)
-		uniform mat4 lightMatrix3;
-		varying vec4 vPositionFromLight3;
+	#if defined(SPOTLIGHT{X}) || defined(DIRLIGHT{X})
+		uniform mat4 lightMatrix{X};
+		varying vec4 vPositionFromLight{X};
 	#endif
 #endif

+ 2 - 2
src/Shaders/default.vertex.fx

@@ -78,7 +78,7 @@ varying vec4 vColor;
 #include<clipPlaneVertexDeclaration>
 
 #include<fogVertexDeclaration>
-#include<shadowsVertexDeclaration>
+#include<shadowsVertexDeclaration>[0..maxSimultaneousLights]
 
 #ifdef REFLECTIONMAP_SKYBOX
 varying vec3 vPositionUVW;
@@ -198,7 +198,7 @@ void main(void) {
 
 #include<clipPlaneVertex>
 #include<fogVertex>
-#include<shadowsVertex>
+#include<shadowsVertex>[0..maxSimultaneousLights]
 
 	// Vertex color
 #ifdef VERTEXCOLOR

+ 2 - 2
src/Shaders/legacydefault.vertex.fx

@@ -63,7 +63,7 @@ varying vec4 vColor;
 
 #include<clipPlaneVertexDeclaration>
 #include<fogVertexDeclaration>
-#include<shadowsVertexDeclaration>
+#include<shadowsVertexDeclaration>[0..maxSimultaneousLights]
 
 #ifdef REFLECTION
 uniform vec3 vEyePosition;
@@ -199,7 +199,7 @@ void main(void) {
 
 #include<clipPlaneVertex>
 #include<fogVertex>
-#include<shadowsVertex>
+#include<shadowsVertex>[0..maxSimultaneousLights]
 
 	// Vertex color
 #ifdef VERTEXCOLOR

+ 2 - 2
src/Shaders/pbr.vertex.fx

@@ -82,7 +82,7 @@ varying vec4 vColor;
 
 #include<clipPlaneVertexDeclaration>
 #include<fogVertexDeclaration>
-#include<shadowsVertexDeclaration>
+#include<shadowsVertexDeclaration>[0..maxSimultaneousLights]
 
 #ifdef REFLECTIONMAP_SKYBOX
 varying vec3 vPositionUVW;
@@ -207,7 +207,7 @@ void main(void) {
 #include<fogVertex>
 
     // Shadows
-#include<shadowsVertex>
+#include<shadowsVertex>[0..maxSimultaneousLights]
 
     // Vertex color
 #ifdef VERTEXCOLOR