diff options
author | Dmitry Kostenko <codeforsmile@gmail.com> | 2021-11-04 03:03:10 +0100 |
---|---|---|
committer | x2048 <codeforsmile@gmail.com> | 2022-03-07 23:45:26 +0100 |
commit | 54dccc480eb03adcf219a7add58f547284f40f76 (patch) | |
tree | 53ca69960e1d4bd2facc35368094106b49b56053 | |
parent | f2cccf8da72c39299c8e7ba6ad8f782a7d61b883 (diff) | |
download | minetest-54dccc480eb03adcf219a7add58f547284f40f76.tar.gz minetest-54dccc480eb03adcf219a7add58f547284f40f76.tar.bz2 minetest-54dccc480eb03adcf219a7add58f547284f40f76.zip |
Improve lighting of entities.
Pass correct natural & artificial light to the shaders
Use natural/artificial light ratio for correct rendering of shadows
-rw-r--r-- | client/shaders/object_shader/opengl_fragment.glsl | 2 | ||||
-rw-r--r-- | client/shaders/object_shader/opengl_vertex.glsl | 30 | ||||
-rw-r--r-- | src/client/content_cao.cpp | 34 | ||||
-rw-r--r-- | src/client/content_cao.h | 4 | ||||
-rw-r--r-- | src/client/wieldmesh.cpp | 5 |
5 files changed, 50 insertions, 25 deletions
diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index 674b6a739..0dcbbd321 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -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; diff --git a/client/shaders/object_shader/opengl_vertex.glsl b/client/shaders/object_shader/opengl_vertex.glsl index 922fba62b..9ca5ef0f3 100644 --- a/client/shaders/object_shader/opengl_vertex.glsl +++ b/client/shaders/object_shader/opengl_vertex.glsl @@ -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); diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 03a2ee830..c7ab5a347 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -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); } } } diff --git a/src/client/content_cao.h b/src/client/content_cao.h index 4bbba9134..70f1557e1 100644 --- a/src/client/content_cao.h +++ b/src/client/content_cao.h @@ -125,7 +125,7 @@ private: 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 @@ public: 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 diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 8b3347df6..ab6fc9281 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -515,8 +515,9 @@ void WieldMeshSceneNode::setNodeLightColor(video::SColor color) material.EmissiveColor = color; } } - - setColor(color); + else { + setColor(color); + } } void WieldMeshSceneNode::render() |