aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kostenko <codeforsmile@gmail.com>2021-11-04 03:03:10 +0100
committerx2048 <codeforsmile@gmail.com>2022-03-07 23:45:26 +0100
commit54dccc480eb03adcf219a7add58f547284f40f76 (patch)
tree53ca69960e1d4bd2facc35368094106b49b56053
parentf2cccf8da72c39299c8e7ba6ad8f782a7d61b883 (diff)
downloadminetest-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.glsl2
-rw-r--r--client/shaders/object_shader/opengl_vertex.glsl30
-rw-r--r--src/client/content_cao.cpp34
-rw-r--r--src/client/content_cao.h4
-rw-r--r--src/client/wieldmesh.cpp5
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()