|
@@ -7,165 +7,161 @@
|
|
return dot(color, bit_shift);
|
|
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
|
|
#ifdef OVERLOADEDSHADOWVALUES
|
|
- return min(1.0, mix(1.0, visibility + darkness, vOverloadedShadowIntensity.x));
|
|
|
|
|
|
+ return mix(1.0, darkness, vOverloadedShadowIntensity.x);
|
|
#else
|
|
#else
|
|
- return min(1.0, visibility + darkness);
|
|
|
|
|
|
+ return darkness;
|
|
#endif
|
|
#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
|
|
#endif
|