]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Improve lighting of entities.
authorDmitry Kostenko <codeforsmile@gmail.com>
Thu, 4 Nov 2021 02:03:10 +0000 (03:03 +0100)
committerx2048 <codeforsmile@gmail.com>
Mon, 7 Mar 2022 22:45:26 +0000 (23:45 +0100)
Pass correct natural & artificial light to the shaders
Use natural/artificial light ratio for correct rendering of shadows

client/shaders/object_shader/opengl_fragment.glsl
client/shaders/object_shader/opengl_vertex.glsl
src/client/content_cao.cpp
src/client/content_cao.h
src/client/wieldmesh.cpp

index 674b6a7393196b28f5907f338fbfe6d17115789c..0dcbbd32186815d538918a9dae02423cad1a6190 100644 (file)
@@ -471,7 +471,7 @@ void main(void)
        color = base.rgb;
        vec4 col = vec4(color.rgb, base.a);
        col.rgb *= varColor.rgb;
-       col.rgb *= emissiveColor.rgb * vIDiff;
+       col.rgb *= vIDiff;
 
 #ifdef ENABLE_DYNAMIC_SHADOWS
        float shadow_int = 0.0;
index 922fba62bd19bc4ef6c377080ffcae19f3d4d35c..9ca5ef0f38993b615d9d364d6723fd746932326c 100644 (file)
@@ -1,7 +1,9 @@
 uniform mat4 mWorld;
-
+uniform vec3 dayLight;
 uniform vec3 eyePosition;
 uniform float animationTimer;
+uniform vec4 emissiveColor;
+
 
 varying vec3 vNormal;
 varying vec3 vPosition;
@@ -29,9 +31,9 @@ centroid varying vec2 varTexCoord;
 
 varying vec3 eyeVec;
 varying float nightRatio;
-
+// Color of the light emitted by the light sources.
+const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
 varying float vIDiff;
-
 const float e = 2.718281828459;
 const float BS = 10.0;
 
@@ -75,14 +77,30 @@ void main(void)
                ? 1.0
                : directional_ambient(normalize(inVertexNormal));
 #endif
-       nightRatio = 0.0;
 
 #ifdef GL_ES
-       varColor = inVertexColor.bgra;
+       vec4 color = inVertexColor.bgra;
 #else
-       varColor = inVertexColor;
+       vec4 color = inVertexColor;
 #endif
 
+       color *= emissiveColor;
+
+       // The alpha gives the ratio of sunlight in the incoming light.
+       nightRatio = 1.0 - color.a;
+       color.rgb = color.rgb * (color.a * dayLight.rgb +
+               nightRatio * artificialLight.rgb) * 2.0;
+       color.a = 1.0;
+
+       // Emphase blue a bit in darker places
+       // See C++ implementation in mapblock_mesh.cpp final_color_blend()
+       float brightness = (color.r + color.g + color.b) / 3.0;
+       color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
+               0.07 * brightness);
+
+       varColor = clamp(color, 0.0, 1.0);
+
+
 #ifdef ENABLE_DYNAMIC_SHADOWS
        vec3 nNormal = normalize(vNormal);
        cosLight = dot(nNormal, -v_LightDirection);
index 03a2ee8302a73566a607da0bc9a2fc7a78a62418..c7ab5a3477d9f6a5635e69686b1dc484d56b2f68 100644 (file)
@@ -864,7 +864,8 @@ void GenericCAO::updateLight(u32 day_night_ratio)
        if (m_glow < 0)
                return;
 
-       u8 light_at_pos = 0;
+       u16 light_at_pos = 0;
+       u8 light_at_pos_intensity = 0;
        bool pos_ok = false;
 
        v3s16 pos[3];
@@ -873,28 +874,33 @@ void GenericCAO::updateLight(u32 day_night_ratio)
                bool this_ok;
                MapNode n = m_env->getMap().getNode(pos[i], &this_ok);
                if (this_ok) {
-                       u8 this_light = n.getLightBlend(day_night_ratio, m_client->ndef());
-                       light_at_pos = MYMAX(light_at_pos, this_light);
+                       u16 this_light = getInteriorLight(n, 0, m_client->ndef());
+                       u8 this_light_intensity = MYMAX(this_light & 0xFF, (this_light >> 8) && 0xFF);
+                       if (this_light_intensity > light_at_pos_intensity) {
+                               light_at_pos = this_light;
+                               light_at_pos_intensity = this_light_intensity;
+                       }
                        pos_ok = true;
                }
        }
        if (!pos_ok)
-               light_at_pos = blend_light(day_night_ratio, LIGHT_SUN, 0);
+               light_at_pos = LIGHT_SUN;
+
+       video::SColor light = encode_light(light_at_pos, m_glow);
+       if (!m_enable_shaders)
+               final_color_blend(&light, light_at_pos, day_night_ratio);
 
-       u8 light = decode_light(light_at_pos + m_glow);
        if (light != m_last_light) {
                m_last_light = light;
                setNodeLight(light);
        }
 }
 
-void GenericCAO::setNodeLight(u8 light)
+void GenericCAO::setNodeLight(const video::SColor &light_color)
 {
-       video::SColor color(255, light, light, light);
-
        if (m_prop.visual == "wielditem" || m_prop.visual == "item") {
                if (m_wield_meshnode)
-                       m_wield_meshnode->setNodeLightColor(color);
+                       m_wield_meshnode->setNodeLightColor(light_color);
                return;
        }
 
@@ -906,7 +912,7 @@ void GenericCAO::setNodeLight(u8 light)
                        scene::IMesh *mesh = m_meshnode->getMesh();
                        for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
                                scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
-                               buf->getMaterial().EmissiveColor = color;
+                               buf->getMaterial().EmissiveColor = light_color;
                        }
                } else {
                        scene::ISceneNode *node = getSceneNode();
@@ -915,16 +921,16 @@ void GenericCAO::setNodeLight(u8 light)
 
                        for (u32 i = 0; i < node->getMaterialCount(); ++i) {
                                video::SMaterial &material = node->getMaterial(i);
-                               material.EmissiveColor = color;
+                               material.EmissiveColor = light_color;
                        }
                }
        } else {
                if (m_meshnode) {
-                       setMeshColor(m_meshnode->getMesh(), color);
+                       setMeshColor(m_meshnode->getMesh(), light_color);
                } else if (m_animated_meshnode) {
-                       setAnimatedMeshColor(m_animated_meshnode, color);
+                       setAnimatedMeshColor(m_animated_meshnode, light_color);
                } else if (m_spritenode) {
-                       m_spritenode->setColor(color);
+                       m_spritenode->setColor(light_color);
                }
        }
 }
index 4bbba91342a5d7506fece1e878d56629f704ee72..70f1557e1812e39b7ce5e81a35deb14b1f816487 100644 (file)
@@ -125,7 +125,7 @@ class GenericCAO : public ClientActiveObject
        std::string m_current_texture_modifier = "";
        bool m_visuals_expired = false;
        float m_step_distance_counter = 0.0f;
-       u8 m_last_light = 255;
+       video::SColor m_last_light = video::SColor(0xFFFFFFFF);
        bool m_is_visible = false;
        s8 m_glow = 0;
        // Material
@@ -245,7 +245,7 @@ class GenericCAO : public ClientActiveObject
 
        void updateLight(u32 day_night_ratio);
 
-       void setNodeLight(u8 light);
+       void setNodeLight(const video::SColor &light);
 
        /* Get light position(s).
         * returns number of positions written into pos[], which must have space
index 8b3347df6dc164b0b4ee040ef4ca9f1bf5e845bd..ab6fc9281a1883f45b61e13122fa4f6b01f642a0 100644 (file)
@@ -515,8 +515,9 @@ void WieldMeshSceneNode::setNodeLightColor(video::SColor color)
                        material.EmissiveColor = color;
                }
        }
-
-       setColor(color);
+       else {
+               setColor(color);
+       }
 }
 
 void WieldMeshSceneNode::render()