aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorx2048 <codeforsmile@gmail.com>2022-04-07 22:13:50 +0200
committerGitHub <noreply@github.com>2022-04-07 22:13:50 +0200
commit48f7c5603e5b2dfca941d228e76e452bc269a1fa (patch)
tree7983bb05e762792e38ba22a59e8718cac5381747 /client
parent0b5b2b2633609f646a534d353a2c587af4be46fa (diff)
downloadminetest-48f7c5603e5b2dfca941d228e76e452bc269a1fa.tar.gz
minetest-48f7c5603e5b2dfca941d228e76e452bc269a1fa.tar.bz2
minetest-48f7c5603e5b2dfca941d228e76e452bc269a1fa.zip
Adjust shadowmap distortion to use entire SM texture (#12166)
Diffstat (limited to 'client')
-rw-r--r--client/shaders/nodes_shader/opengl_fragment.glsl25
-rw-r--r--client/shaders/object_shader/opengl_fragment.glsl89
-rw-r--r--client/shaders/shadow_shaders/pass1_trans_vertex.glsl10
-rw-r--r--client/shaders/shadow_shaders/pass1_vertex.glsl10
4 files changed, 83 insertions, 51 deletions
diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl
index 3dc66bdb3..4d0d107d1 100644
--- a/client/shaders/nodes_shader/opengl_fragment.glsl
+++ b/client/shaders/nodes_shader/opengl_fragment.glsl
@@ -17,6 +17,7 @@ uniform float animationTimer;
uniform mat4 m_ShadowViewProj;
uniform float f_shadowfar;
uniform float f_shadow_strength;
+ uniform vec4 CameraPos;
varying float normalOffsetScale;
varying float adj_shadow_strength;
varying float cosLight;
@@ -53,12 +54,13 @@ uniform float zPerspectiveBias;
vec4 getPerspectiveFactor(in vec4 shadowPosition)
{
-
- float pDistance = length(shadowPosition.xy);
+ vec2 s = vec2(shadowPosition.x > CameraPos.x ? 1.0 : -1.0, shadowPosition.y > CameraPos.y ? 1.0 : -1.0);
+ vec2 l = s * (shadowPosition.xy - CameraPos.xy) / (1.0 - s * CameraPos.xy);
+ float pDistance = length(l);
float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
-
- shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPerspectiveBias);
-
+ l /= pFactor;
+ shadowPosition.xy = CameraPos.xy * (1.0 - l) + s * l;
+ shadowPosition.z *= zPerspectiveBias;
return shadowPosition;
}
@@ -171,13 +173,13 @@ float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDis
float getBaseLength(vec2 smTexCoord)
{
- float l = length(2.0 * smTexCoord.xy - 1.0); // length in texture coords
+ float l = length(2.0 * smTexCoord.xy - 1.0 - CameraPos.xy); // length in texture coords
return xyPerspectiveBias1 / (1.0 / l - xyPerspectiveBias0); // return to undistorted coords
}
float getDeltaPerspectiveFactor(float l)
{
- return 0.1 / (xyPerspectiveBias0 * l + xyPerspectiveBias1); // original distortion factor, divided by 10
+ return 0.04 * pow(512.0 / f_textureresolution, 0.4) / (xyPerspectiveBias0 * l + xyPerspectiveBias1); // original distortion factor, divided by 10
}
float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDistance, float multiplier)
@@ -185,7 +187,6 @@ float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDist
float baseLength = getBaseLength(smTexCoord);
float perspectiveFactor;
- if (PCFBOUND == 0.0) return 0.0;
// Return fast if sharp shadows are requested
if (PCFBOUND == 0.0)
return 0.0;
@@ -489,11 +490,13 @@ void main(void)
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
vec3 posLightSpace = getLightSpacePosition();
- float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 50.0));
+ float distance_rate = (1.0 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 10.0));
+ if (max(abs(posLightSpace.x - 0.5), abs(posLightSpace.y - 0.5)) > 0.5)
+ distance_rate = 0.0;
float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z),0.0);
if (distance_rate > 1e-7) {
-
+
#ifdef COLORED_SHADOWS
vec4 visibility;
if (cosLight > 0.0)
@@ -527,7 +530,7 @@ void main(void)
}
shadow_int *= f_adj_shadow_strength;
-
+
// calculate fragment color from components:
col.rgb =
adjusted_night_ratio * col.rgb + // artificial light
diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl
index 2b9a59cd7..2611bf8ef 100644
--- a/client/shaders/object_shader/opengl_fragment.glsl
+++ b/client/shaders/object_shader/opengl_fragment.glsl
@@ -6,8 +6,33 @@ uniform vec4 skyBgColor;
uniform float fogDistance;
uniform vec3 eyePosition;
+// The cameraOffset is the current center of the visible world.
+uniform vec3 cameraOffset;
+uniform float animationTimer;
+#ifdef ENABLE_DYNAMIC_SHADOWS
+ // shadow texture
+ uniform sampler2D ShadowMapSampler;
+ // shadow uniforms
+ uniform vec3 v_LightDirection;
+ uniform float f_textureresolution;
+ uniform mat4 m_ShadowViewProj;
+ uniform float f_shadowfar;
+ uniform float f_shadow_strength;
+ uniform vec4 CameraPos;
+ varying float normalOffsetScale;
+ varying float adj_shadow_strength;
+ varying float cosLight;
+ varying float f_normal_length;
+#endif
+
+
varying vec3 vNormal;
varying vec3 vPosition;
+// World position in the visible world (i.e. relative to the cameraOffset.)
+// This can be used for many shader effects without loss of precision.
+// If the absolute position is required it can be calculated with
+// cameraOffset + worldPosition (for large coordinates the limits of float
+// precision must be considered).
varying vec3 worldPosition;
varying lowp vec4 varColor;
#ifdef GL_ES
@@ -15,32 +40,15 @@ varying mediump vec2 varTexCoord;
#else
centroid varying vec2 varTexCoord;
#endif
-
varying vec3 eyeVec;
varying float nightRatio;
varying float vIDiff;
-const float e = 2.718281828459;
-const float BS = 10.0;
const float fogStart = FOG_START;
const float fogShadingParameter = 1.0 / (1.0 - fogStart);
-#ifdef ENABLE_DYNAMIC_SHADOWS
- // shadow texture
- uniform sampler2D ShadowMapSampler;
- // shadow uniforms
- uniform vec3 v_LightDirection;
- uniform float f_textureresolution;
- uniform mat4 m_ShadowViewProj;
- uniform float f_shadowfar;
- uniform float f_timeofday;
- uniform float f_shadow_strength;
- varying float normalOffsetScale;
- varying float adj_shadow_strength;
- varying float cosLight;
- varying float f_normal_length;
-#endif
+
#ifdef ENABLE_DYNAMIC_SHADOWS
uniform float xyPerspectiveBias0;
@@ -49,15 +57,22 @@ uniform float zPerspectiveBias;
vec4 getPerspectiveFactor(in vec4 shadowPosition)
{
-
- float pDistance = length(shadowPosition.xy);
+ vec2 s = vec2(shadowPosition.x > CameraPos.x ? 1.0 : -1.0, shadowPosition.y > CameraPos.y ? 1.0 : -1.0);
+ vec2 l = s * (shadowPosition.xy - CameraPos.xy) / (1.0 - s * CameraPos.xy);
+ float pDistance = length(l);
float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
-
- shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPerspectiveBias);
-
+ l /= pFactor;
+ shadowPosition.xy = CameraPos.xy * (1.0 - l) + s * l;
+ shadowPosition.z *= zPerspectiveBias;
return shadowPosition;
}
+// assuming near is always 1.0
+float getLinearDepth()
+{
+ return 2.0 * f_shadowfar / (f_shadowfar + 1.0 - (2.0 * gl_FragCoord.z - 1.0) * (f_shadowfar - 1.0));
+}
+
vec3 getLightSpacePosition()
{
vec4 pLightSpace;
@@ -161,13 +176,13 @@ float getHardShadowDepth(sampler2D shadowsampler, vec2 smTexCoord, float realDis
float getBaseLength(vec2 smTexCoord)
{
- float l = length(2.0 * smTexCoord.xy - 1.0); // length in texture coords
+ float l = length(2.0 * smTexCoord.xy - 1.0 - CameraPos.xy); // length in texture coords
return xyPerspectiveBias1 / (1.0 / l - xyPerspectiveBias0); // return to undistorted coords
}
float getDeltaPerspectiveFactor(float l)
{
- return 0.1 / (xyPerspectiveBias0 * l + xyPerspectiveBias1); // original distortion factor, divided by 10
+ return 0.04 * pow(512.0 / f_textureresolution, 0.4) / (xyPerspectiveBias0 * l + xyPerspectiveBias1); // original distortion factor, divided by 10
}
float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDistance, float multiplier)
@@ -178,7 +193,7 @@ float getPenumbraRadius(sampler2D shadowsampler, vec2 smTexCoord, float realDist
// Return fast if sharp shadows are requested
if (PCFBOUND == 0.0)
return 0.0;
-
+
if (SOFTSHADOWRADIUS <= 1.0) {
perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
return max(2 * length(smTexCoord.xy) * 2048 / f_textureresolution / pow(perspectiveFactor, 3), SOFTSHADOWRADIUS);
@@ -418,6 +433,7 @@ float getShadow(sampler2D shadowsampler, vec2 smTexCoord, float realDistance)
#endif
#if ENABLE_TONE_MAPPING
+
/* Hable's UC2 Tone mapping parameters
A = 0.22;
B = 0.30;
@@ -448,12 +464,14 @@ vec4 applyToneMapping(vec4 color)
}
#endif
+
+
void main(void)
{
vec3 color;
vec2 uv = varTexCoord.st;
- vec4 base = texture2D(baseTexture, uv).rgba;
+ vec4 base = texture2D(baseTexture, uv).rgba;
// If alpha is zero, we can just discard the pixel. This fixes transparency
// on GPUs like GC7000L, where GL_ALPHA_TEST is not implemented in mesa,
// and also on GLES 2, where GL_ALPHA_TEST is missing entirely.
@@ -467,8 +485,7 @@ void main(void)
#endif
color = base.rgb;
- vec4 col = vec4(color.rgb, base.a);
- col.rgb *= varColor.rgb;
+ vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
col.rgb *= vIDiff;
#ifdef ENABLE_DYNAMIC_SHADOWS
@@ -477,11 +494,13 @@ void main(void)
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
vec3 posLightSpace = getLightSpacePosition();
- float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 50.0));
+ float distance_rate = (1.0 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 10.0));
+ if (max(abs(posLightSpace.x - 0.5), abs(posLightSpace.y - 0.5)) > 0.5)
+ distance_rate = 0.0;
float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z),0.0);
if (distance_rate > 1e-7) {
-
+
#ifdef COLORED_SHADOWS
vec4 visibility;
if (cosLight > 0.0)
@@ -506,8 +525,8 @@ void main(void)
// Power ratio was measured on torches in MTG (brightness = 14).
float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
- // cosine of the normal-to-light angle when
- // we start to apply self-shadowing
+ // Apply self-shadowing when light falls at a narrow angle to the surface
+ // Cosine of the cut-off angle.
const float self_shadow_cutoff_cosine = 0.14;
if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) {
shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
@@ -541,5 +560,7 @@ void main(void)
float clarity = clamp(fogShadingParameter
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
col = mix(skyBgColor, col, clarity);
- gl_FragColor = vec4(col.rgb, base.a);
+ col = vec4(col.rgb, base.a);
+
+ gl_FragColor = col;
}
diff --git a/client/shaders/shadow_shaders/pass1_trans_vertex.glsl b/client/shaders/shadow_shaders/pass1_trans_vertex.glsl
index 6d2877d18..c2f575876 100644
--- a/client/shaders/shadow_shaders/pass1_trans_vertex.glsl
+++ b/client/shaders/shadow_shaders/pass1_trans_vertex.glsl
@@ -1,4 +1,5 @@
uniform mat4 LightMVP; // world matrix
+uniform vec4 CameraPos;
varying vec4 tPos;
#ifdef COLORED_SHADOWS
varying vec3 varColor;
@@ -10,10 +11,13 @@ uniform float zPerspectiveBias;
vec4 getPerspectiveFactor(in vec4 shadowPosition)
{
- float pDistance = length(shadowPosition.xy);
+ vec2 s = vec2(shadowPosition.x > CameraPos.x ? 1.0 : -1.0, shadowPosition.y > CameraPos.y ? 1.0 : -1.0);
+ vec2 l = s * (shadowPosition.xy - CameraPos.xy) / (1.0 - s * CameraPos.xy);
+ float pDistance = length(l);
float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
- shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPerspectiveBias);
-
+ l /= pFactor;
+ shadowPosition.xy = CameraPos.xy * (1.0 - l) + s * l;
+ shadowPosition.z *= zPerspectiveBias;
return shadowPosition;
}
diff --git a/client/shaders/shadow_shaders/pass1_vertex.glsl b/client/shaders/shadow_shaders/pass1_vertex.glsl
index 3873ac6e6..38aef3619 100644
--- a/client/shaders/shadow_shaders/pass1_vertex.glsl
+++ b/client/shaders/shadow_shaders/pass1_vertex.glsl
@@ -1,4 +1,5 @@
uniform mat4 LightMVP; // world matrix
+uniform vec4 CameraPos; // camera position
varying vec4 tPos;
uniform float xyPerspectiveBias0;
@@ -7,10 +8,13 @@ uniform float zPerspectiveBias;
vec4 getPerspectiveFactor(in vec4 shadowPosition)
{
- float pDistance = length(shadowPosition.xy);
+ vec2 s = vec2(shadowPosition.x > CameraPos.x ? 1.0 : -1.0, shadowPosition.y > CameraPos.y ? 1.0 : -1.0);
+ vec2 l = s * (shadowPosition.xy - CameraPos.xy) / (1.0 - s * CameraPos.xy);
+ float pDistance = length(l);
float pFactor = pDistance * xyPerspectiveBias0 + xyPerspectiveBias1;
- shadowPosition.xyz *= vec3(vec2(1.0 / pFactor), zPerspectiveBias);
-
+ l /= pFactor;
+ shadowPosition.xy = CameraPos.xy * (1.0 - l) + s * l;
+ shadowPosition.z *= zPerspectiveBias;
return shadowPosition;
}