]> git.lizzy.rs Git - minetest.git/commitdiff
Improvements to colored shadows (#11516)
authorx2048 <codeforsmile@gmail.com>
Fri, 1 Oct 2021 14:21:53 +0000 (16:21 +0200)
committerGitHub <noreply@github.com>
Fri, 1 Oct 2021 14:21:53 +0000 (16:21 +0200)
client/shaders/nodes_shader/opengl_fragment.glsl
client/shaders/object_shader/opengl_fragment.glsl
client/shaders/shadow_shaders/pass1_trans_fragment.glsl
client/shaders/shadow_shaders/pass1_trans_vertex.glsl
src/client/clientmap.cpp

index 87ef9af7d649d3c16b52ff91a91b58a2b5194062..e21890710bf738357b5d923b7a53a9c381ffac20 100644 (file)
@@ -489,7 +489,11 @@ void main(void)
        if (distance_rate > 1e-7) {
        
 #ifdef COLORED_SHADOWS
-               vec4 visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+               vec4 visibility;
+               if (cosLight > 0.0)
+                       visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+               else
+                       visibility = vec4(1.0, 0.0, 0.0, 0.0);
                shadow_int = visibility.r;
                shadow_color = visibility.gba;
 #else
@@ -507,7 +511,8 @@ void main(void)
 
        shadow_int = 1.0 - (shadow_int * f_adj_shadow_strength);
        
-       col.rgb = mix(shadow_color,col.rgb,shadow_int)*shadow_int;
+       // apply shadow (+color) as a factor to the material color
+       col.rgb = col.rgb * (1.0 - (1.0 - shadow_color) * (1.0 - pow(shadow_int, 2.0)));
        // col.r = 0.5 * clamp(getPenumbraRadius(ShadowMapSampler, posLightSpace.xy, posLightSpace.z, 1.0) / SOFTSHADOWRADIUS, 0.0, 1.0) + 0.5 * col.r;
 #endif
 
index 9a0b90f158a74406e1f389f3814c7fe7cf32e309..3390e72277e21ba169c61012f9115ce9c525f67b 100644 (file)
@@ -351,7 +351,11 @@ void main(void)
        vec3 posLightSpace = getLightSpacePosition();
 
 #ifdef COLORED_SHADOWS
-       vec4 visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+       vec4 visibility;
+       if (cosLight > 0.0)
+               visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+       else
+               visibility = vec4(1.0, 0.0, 0.0, 0.0);
        shadow_int = visibility.r;
        shadow_color = visibility.gba;
 #else
index 9f9e5be8cce29c2c69de9310d15506179961a1a8..032cd93798c436e8e81afb9a092c7ab9803bce93 100644 (file)
@@ -2,6 +2,8 @@ uniform sampler2D ColorMapSampler;
 varying vec4 tPos;
 
 #ifdef COLORED_SHADOWS
+varying vec3 varColor;
+
 // c_precision of 128 fits within 7 base-10 digits
 const float c_precision = 128.0;
 const float c_precisionp1 = c_precision + 1.0;
@@ -30,7 +32,10 @@ void main()
 
        //col.rgb = col.a == 1.0 ? vec3(1.0) : col.rgb;
 #ifdef COLORED_SHADOWS
-       float packedColor = packColor(mix(col.rgb, black, col.a));
+       col.rgb *= varColor.rgb;
+       // alpha 0.0 results in all-white, 0.5 means full color, 1.0 means all black
+       // resulting color is used as a factor in the final shader
+       float packedColor = packColor(mix(mix(vec3(1.0), col.rgb, 2.0 * clamp(col.a, 0.0, 0.5)), black, 2.0 * clamp(col.a - 0.5, 0.0, 0.5)));
        gl_FragColor = vec4(depth, packedColor, 0.0,1.0);
 #else
        gl_FragColor = vec4(depth, 0.0, 0.0, 1.0);
index ca59f27966e48aa38776e51ff47c11ca5a1222ea..0a9efe450e3f4b01055f6c2c9ea37c7c0454807e 100644 (file)
@@ -1,5 +1,8 @@
 uniform mat4 LightMVP; // world matrix
 varying vec4 tPos;
+#ifdef COLORED_SHADOWS
+varying vec3 varColor;
+#endif
 
 const float bias0 = 0.9;
 const float zPersFactor = 0.5;
@@ -23,4 +26,8 @@ void main()
 
        gl_Position = vec4(tPos.xyz, 1.0);
        gl_TexCoord[0].st = gl_MultiTexCoord0.st;
+
+#ifdef COLORED_SHADOWS
+       varColor = gl_Color.rgb;
+#endif
 }
index 7cde085c830685382978d10a42d584bb0a42ba98..1a024e464b75698bf9999649112ce945ff2042f4 100644 (file)
@@ -461,7 +461,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                                layer.Texture = shadow->get_texture();
                                layer.TextureWrapU = video::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE;
                                layer.TextureWrapV = video::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE;
-                               layer.TrilinearFilter = true;
+                               // Do not enable filter on shadow texture to avoid visual artifacts
+                               // with colored shadows.
+                               // Filtering is done in shader code anyway
+                               layer.TrilinearFilter = false;
                        }
                        driver->setMaterial(material);
                        ++material_swaps;