aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorx2048 <codeforsmile@gmail.com>2022-03-26 16:58:26 +0100
committerGitHub <noreply@github.com>2022-03-26 16:58:26 +0100
commit0f25fa7af655b98fa401176a523f269c843d1943 (patch)
tree1fa8762f53941d6c1250c0c3a7dc6b8557995a40
parent8d55702d139db739f8bf43eaa600f41446b29a16 (diff)
downloadminetest-0f25fa7af655b98fa401176a523f269c843d1943.tar.gz
minetest-0f25fa7af655b98fa401176a523f269c843d1943.tar.bz2
minetest-0f25fa7af655b98fa401176a523f269c843d1943.zip
Add API to control shadow intensity from the game/mod (#11944)
* Also Disable shadows when sun/moon is hidden. Fixes #11972.
-rw-r--r--builtin/settingtypes.txt5
-rw-r--r--client/shaders/nodes_shader/opengl_fragment.glsl85
-rw-r--r--client/shaders/nodes_shader/opengl_vertex.glsl57
-rw-r--r--client/shaders/object_shader/opengl_fragment.glsl84
-rw-r--r--client/shaders/object_shader/opengl_vertex.glsl56
-rw-r--r--doc/lua_api.txt7
-rw-r--r--games/devtest/mods/experimental/init.lua1
-rw-r--r--games/devtest/mods/experimental/lighting.lua8
-rw-r--r--src/client/client.h1
-rw-r--r--src/client/game.cpp7
-rw-r--r--src/client/localplayer.h4
-rw-r--r--src/client/shadows/dynamicshadowsrender.cpp95
-rw-r--r--src/client/shadows/dynamicshadowsrender.h10
-rw-r--r--src/client/sky.h2
-rw-r--r--src/defaultsettings.cpp2
-rw-r--r--src/lighting.h27
-rw-r--r--src/network/clientopcodes.cpp1
-rw-r--r--src/network/clientpackethandler.cpp8
-rw-r--r--src/network/networkprotocol.h7
-rw-r--r--src/remoteplayer.h7
-rw-r--r--src/script/lua_api/l_object.cpp43
-rw-r--r--src/script/lua_api/l_object.h6
-rw-r--r--src/server.cpp17
-rw-r--r--src/server.h4
24 files changed, 375 insertions, 169 deletions
diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt
index ff2d72927..3dc165bd1 100644
--- a/builtin/settingtypes.txt
+++ b/builtin/settingtypes.txt
@@ -592,9 +592,10 @@ enable_waving_plants (Waving plants) bool false
# Requires shaders to be enabled.
enable_dynamic_shadows (Dynamic shadows) bool false
-# Set the shadow strength.
+# Set the shadow strength gamma.
+# Adjusts the intensity of in-game dynamic shadows.
# Lower value means lighter shadows, higher value means darker shadows.
-shadow_strength (Shadow strength) float 0.2 0.05 1.0
+shadow_strength_gamma (Shadow strength gamma) float 1.0 0.1 10.0
# Maximum distance to render shadows.
shadow_map_max_distance (Shadow map max distance in nodes to render shadows) float 120.0 10.0 1000.0
diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl
index e5f5c703a..adc8adccb 100644
--- a/client/shaders/nodes_shader/opengl_fragment.glsl
+++ b/client/shaders/nodes_shader/opengl_fragment.glsl
@@ -16,6 +16,7 @@ uniform float animationTimer;
uniform float f_textureresolution;
uniform mat4 m_ShadowViewProj;
uniform float f_shadowfar;
+ uniform float f_shadow_strength;
varying float normalOffsetScale;
varying float adj_shadow_strength;
varying float cosLight;
@@ -483,55 +484,57 @@ void main(void)
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
#ifdef ENABLE_DYNAMIC_SHADOWS
- float shadow_int = 0.0;
- vec3 shadow_color = vec3(0.0, 0.0, 0.0);
- vec3 posLightSpace = getLightSpacePosition();
+ if (f_shadow_strength > 0.0) {
+ float shadow_int = 0.0;
+ 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), 20.0));
- float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
+ float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 20.0));
+ float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
- if (distance_rate > 1e-7) {
-
+ if (distance_rate > 1e-7) {
+
#ifdef COLORED_SHADOWS
- 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;
+ 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
- if (cosLight > 0.0)
- shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
- else
- shadow_int = 1.0;
+ if (cosLight > 0.0)
+ shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+ else
+ shadow_int = 1.0;
#endif
- shadow_int *= distance_rate;
- shadow_int = clamp(shadow_int, 0.0, 1.0);
+ shadow_int *= distance_rate;
+ shadow_int = clamp(shadow_int, 0.0, 1.0);
- }
+ }
- // turns out that nightRatio falls off much faster than
- // actual brightness of artificial light in relation to natual light.
- // Power ratio was measured on torches in MTG (brightness = 14).
- float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
-
- // 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.035;
- 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);
- shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
- }
+ // turns out that nightRatio falls off much faster than
+ // actual brightness of artificial light in relation to natual light.
+ // Power ratio was measured on torches in MTG (brightness = 14).
+ float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
+
+ // 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.035;
+ 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);
+ shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
+ }
- shadow_int *= f_adj_shadow_strength;
-
- // calculate fragment color from components:
- col.rgb =
- adjusted_night_ratio * col.rgb + // artificial light
- (1.0 - adjusted_night_ratio) * ( // natural light
- col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
- dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
+ shadow_int *= f_adj_shadow_strength;
+
+ // calculate fragment color from components:
+ col.rgb =
+ adjusted_night_ratio * col.rgb + // artificial light
+ (1.0 - adjusted_night_ratio) * ( // natural light
+ col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
+ dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
+ }
#endif
#if ENABLE_TONE_MAPPING
diff --git a/client/shaders/nodes_shader/opengl_vertex.glsl b/client/shaders/nodes_shader/opengl_vertex.glsl
index 95cd138a8..5e77ac719 100644
--- a/client/shaders/nodes_shader/opengl_vertex.glsl
+++ b/client/shaders/nodes_shader/opengl_vertex.glsl
@@ -195,34 +195,35 @@ void main(void)
varColor = clamp(color, 0.0, 1.0);
#ifdef ENABLE_DYNAMIC_SHADOWS
- vec3 nNormal = normalize(vNormal);
- cosLight = dot(nNormal, -v_LightDirection);
-
- // Calculate normal offset scale based on the texel size adjusted for
- // curvature of the SM texture. This code must be change together with
- // getPerspectiveFactor or any light-space transformation.
- vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset;
- // Distance from the vertex to the player
- float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar;
- // perspective factor estimation according to the
- float perspectiveFactor = distanceToPlayer * bias0 + bias1;
- float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor /
- (f_textureresolution * bias1 - perspectiveFactor * bias0);
- float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0);
- normalOffsetScale = texelSize * slopeScale;
-
- if (f_timeofday < 0.2) {
- adj_shadow_strength = f_shadow_strength * 0.5 *
- (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
- } else if (f_timeofday >= 0.8) {
- adj_shadow_strength = f_shadow_strength * 0.5 *
- mtsmoothstep(0.8, 0.83, f_timeofday);
- } else {
- adj_shadow_strength = f_shadow_strength *
- mtsmoothstep(0.20, 0.25, f_timeofday) *
- (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
+ if (f_shadow_strength > 0.0) {
+ vec3 nNormal = normalize(vNormal);
+ cosLight = dot(nNormal, -v_LightDirection);
+
+ // Calculate normal offset scale based on the texel size adjusted for
+ // curvature of the SM texture. This code must be change together with
+ // getPerspectiveFactor or any light-space transformation.
+ vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset;
+ // Distance from the vertex to the player
+ float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar;
+ // perspective factor estimation according to the
+ float perspectiveFactor = distanceToPlayer * bias0 + bias1;
+ float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor /
+ (f_textureresolution * bias1 - perspectiveFactor * bias0);
+ float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0);
+ normalOffsetScale = texelSize * slopeScale;
+
+ if (f_timeofday < 0.2) {
+ adj_shadow_strength = f_shadow_strength * 0.5 *
+ (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
+ } else if (f_timeofday >= 0.8) {
+ adj_shadow_strength = f_shadow_strength * 0.5 *
+ mtsmoothstep(0.8, 0.83, f_timeofday);
+ } else {
+ adj_shadow_strength = f_shadow_strength *
+ mtsmoothstep(0.20, 0.25, f_timeofday) *
+ (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
+ }
+ f_normal_length = length(vNormal);
}
- f_normal_length = length(vNormal);
#endif
-
}
diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl
index fdfcec0c8..edb9d2bb1 100644
--- a/client/shaders/object_shader/opengl_fragment.glsl
+++ b/client/shaders/object_shader/opengl_fragment.glsl
@@ -34,6 +34,8 @@ const float fogShadingParameter = 1.0 / (1.0 - fogStart);
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;
@@ -470,55 +472,57 @@ void main(void)
col.rgb *= vIDiff;
#ifdef ENABLE_DYNAMIC_SHADOWS
- float shadow_int = 0.0;
- vec3 shadow_color = vec3(0.0, 0.0, 0.0);
- vec3 posLightSpace = getLightSpacePosition();
+ if (f_shadow_strength > 0.0) {
+ float shadow_int = 0.0;
+ 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), 20.0));
- float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
+ float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 20.0));
+ float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
- if (distance_rate > 1e-7) {
+ if (distance_rate > 1e-7) {
#ifdef COLORED_SHADOWS
- 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;
+ 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
- if (cosLight > 0.0)
- shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
- else
- shadow_int = 1.0;
+ if (cosLight > 0.0)
+ shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
+ else
+ shadow_int = 1.0;
#endif
- shadow_int *= distance_rate;
- shadow_int = clamp(shadow_int, 0.0, 1.0);
+ shadow_int *= distance_rate;
+ shadow_int = clamp(shadow_int, 0.0, 1.0);
- }
+ }
- // turns out that nightRatio falls off much faster than
- // actual brightness of artificial light in relation to natual light.
- // 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
- 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);
- shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
- }
+ // turns out that nightRatio falls off much faster than
+ // actual brightness of artificial light in relation to natual light.
+ // 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
+ 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);
+ shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
+ }
- shadow_int *= f_adj_shadow_strength;
-
- // calculate fragment color from components:
- col.rgb =
- adjusted_night_ratio * col.rgb + // artificial light
- (1.0 - adjusted_night_ratio) * ( // natural light
- col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
- dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
+ shadow_int *= f_adj_shadow_strength;
+
+ // calculate fragment color from components:
+ col.rgb =
+ adjusted_night_ratio * col.rgb + // artificial light
+ (1.0 - adjusted_night_ratio) * ( // natural light
+ col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
+ dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
+ }
#endif
#if ENABLE_TONE_MAPPING
diff --git a/client/shaders/object_shader/opengl_vertex.glsl b/client/shaders/object_shader/opengl_vertex.glsl
index 185551c58..ff0067302 100644
--- a/client/shaders/object_shader/opengl_vertex.glsl
+++ b/client/shaders/object_shader/opengl_vertex.glsl
@@ -105,33 +105,35 @@ void main(void)
#ifdef ENABLE_DYNAMIC_SHADOWS
- vec3 nNormal = normalize(vNormal);
- cosLight = dot(nNormal, -v_LightDirection);
-
- // Calculate normal offset scale based on the texel size adjusted for
- // curvature of the SM texture. This code must be change together with
- // getPerspectiveFactor or any light-space transformation.
- vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset;
- // Distance from the vertex to the player
- float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar;
- // perspective factor estimation according to the
- float perspectiveFactor = distanceToPlayer * bias0 + bias1;
- float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor /
- (f_textureresolution * bias1 - perspectiveFactor * bias0);
- float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0);
- normalOffsetScale = texelSize * slopeScale;
-
- if (f_timeofday < 0.2) {
- adj_shadow_strength = f_shadow_strength * 0.5 *
- (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
- } else if (f_timeofday >= 0.8) {
- adj_shadow_strength = f_shadow_strength * 0.5 *
- mtsmoothstep(0.8, 0.83, f_timeofday);
- } else {
- adj_shadow_strength = f_shadow_strength *
- mtsmoothstep(0.20, 0.25, f_timeofday) *
- (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
+ if (f_shadow_strength > 0.0) {
+ vec3 nNormal = normalize(vNormal);
+ cosLight = dot(nNormal, -v_LightDirection);
+
+ // Calculate normal offset scale based on the texel size adjusted for
+ // curvature of the SM texture. This code must be change together with
+ // getPerspectiveFactor or any light-space transformation.
+ vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset;
+ // Distance from the vertex to the player
+ float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar;
+ // perspective factor estimation according to the
+ float perspectiveFactor = distanceToPlayer * bias0 + bias1;
+ float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor /
+ (f_textureresolution * bias1 - perspectiveFactor * bias0);
+ float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0);
+ normalOffsetScale = texelSize * slopeScale;
+
+ if (f_timeofday < 0.2) {
+ adj_shadow_strength = f_shadow_strength * 0.5 *
+ (1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
+ } else if (f_timeofday >= 0.8) {
+ adj_shadow_strength = f_shadow_strength * 0.5 *
+ mtsmoothstep(0.8, 0.83, f_timeofday);
+ } else {
+ adj_shadow_strength = f_shadow_strength *
+ mtsmoothstep(0.20, 0.25, f_timeofday) *
+ (1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
+ }
+ f_normal_length = length(vNormal);
}
- f_normal_length = length(vNormal);
#endif
}
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 52da17e9c..029c53616 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -7019,6 +7019,13 @@ object you are working with still exists.
* Returns `false` if failed.
* Resource intensive - use sparsely
* To get blockpos, integer divide pos by 16
+* `set_lighting(light_definition)`: sets lighting for the player
+ * `light_definition` is a table with the following optional fields:
+ * `shadows` is a table that controls ambient shadows
+ * `intensity` sets the intensity of the shadows from 0 (no shadows, default) to 1 (blackness)
+ * Returns true on success.
+* `get_lighting()`: returns the current state of lighting for the player.
+ * Result is a table with the same fields as `light_definition` in `set_lighting`.
`PcgRandom`
-----------
diff --git a/games/devtest/mods/experimental/init.lua b/games/devtest/mods/experimental/init.lua
index b292f792e..70091179c 100644
--- a/games/devtest/mods/experimental/init.lua
+++ b/games/devtest/mods/experimental/init.lua
@@ -7,6 +7,7 @@ experimental = {}
dofile(minetest.get_modpath("experimental").."/detached.lua")
dofile(minetest.get_modpath("experimental").."/items.lua")
dofile(minetest.get_modpath("experimental").."/commands.lua")
+dofile(minetest.get_modpath("experimental").."/lighting.lua")
function experimental.print_to_everything(msg)
minetest.log("action", msg)
diff --git a/games/devtest/mods/experimental/lighting.lua b/games/devtest/mods/experimental/lighting.lua
new file mode 100644
index 000000000..2b350550f
--- /dev/null
+++ b/games/devtest/mods/experimental/lighting.lua
@@ -0,0 +1,8 @@
+core.register_chatcommand("set_lighting", {
+ params = "shadow_intensity",
+ description = "Set lighting parameters.",
+ func = function(player_name, param)
+ local shadow_intensity = tonumber(param)
+ minetest.get_player_by_name(player_name):set_lighting({shadows = { intensity = shadow_intensity} })
+ end
+}) \ No newline at end of file
diff --git a/src/client/client.h b/src/client/client.h
index 84c85471d..0e29fdbe2 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -227,6 +227,7 @@ public:
void handleCommand_PlayerSpeed(NetworkPacket *pkt);
void handleCommand_MediaPush(NetworkPacket *pkt);
void handleCommand_MinimapModes(NetworkPacket *pkt);
+ void handleCommand_SetLighting(NetworkPacket *pkt);
void ProcessData(NetworkPacket *pkt);
diff --git a/src/client/game.cpp b/src/client/game.cpp
index 7450fb91c..edc69dcc2 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -4037,7 +4037,12 @@ void Game::updateShadows()
float in_timeofday = fmod(runData.time_of_day_smooth, 1.0f);
- float timeoftheday = fmod(getWickedTimeOfDay(in_timeofday) + 0.75f, 0.5f) + 0.25f;
+ float timeoftheday = getWickedTimeOfDay(in_timeofday);
+ bool is_day = timeoftheday > 0.25 && timeoftheday < 0.75;
+ bool is_shadow_visible = is_day ? sky->getSunVisible() : sky->getMoonVisible();
+ shadow->setShadowIntensity(is_shadow_visible ? client->getEnv().getLocalPlayer()->getLighting().shadow_intensity : 0.0f);
+
+ timeoftheday = fmod(timeoftheday + 0.75f, 0.5f) + 0.25f;
const float offset_constant = 10000.0f;
v3f light(0.0f, 0.0f, -1.0f);
diff --git a/src/client/localplayer.h b/src/client/localplayer.h
index 577be2803..3d0072fc1 100644
--- a/src/client/localplayer.h
+++ b/src/client/localplayer.h
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "environment.h"
#include "constants.h"
#include "settings.h"
+#include "lighting.h"
#include <list>
class Client;
@@ -158,6 +159,8 @@ public:
added_velocity += vel;
}
+ inline Lighting& getLighting() { return m_lighting; }
+
private:
void accelerate(const v3f &target_speed, const f32 max_increase_H,
const f32 max_increase_V, const bool use_pitch);
@@ -209,4 +212,5 @@ private:
GenericCAO *m_cao = nullptr;
Client *m_client;
+ Lighting m_lighting;
};
diff --git a/src/client/shadows/dynamicshadowsrender.cpp b/src/client/shadows/dynamicshadowsrender.cpp
index 528415aaf..24adb21e2 100644
--- a/src/client/shadows/dynamicshadowsrender.cpp
+++ b/src/client/shadows/dynamicshadowsrender.cpp
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include <cstring>
+#include <cmath>
#include "client/shadows/dynamicshadowsrender.h"
#include "client/shadows/shadowsScreenQuad.h"
#include "client/shadows/shadowsshadercallbacks.h"
@@ -33,9 +34,13 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
m_device(device), m_smgr(device->getSceneManager()),
m_driver(device->getVideoDriver()), m_client(client), m_current_frame(0)
{
+ m_shadows_supported = true; // assume shadows supported. We will check actual support in initialize
m_shadows_enabled = true;
- m_shadow_strength = g_settings->getFloat("shadow_strength");
+ m_shadow_strength_gamma = g_settings->getFloat("shadow_strength_gamma");
+ if (std::isnan(m_shadow_strength_gamma))
+ m_shadow_strength_gamma = 1.0f;
+ m_shadow_strength_gamma = core::clamp(m_shadow_strength_gamma, 0.1f, 10.0f);
m_shadow_map_max_distance = g_settings->getFloat("shadow_map_max_distance");
@@ -49,6 +54,9 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
ShadowRenderer::~ShadowRenderer()
{
+ // call to disable releases dynamically allocated resources
+ disable();
+
if (m_shadow_depth_cb)
delete m_shadow_depth_cb;
if (m_shadow_mix_cb)
@@ -72,15 +80,25 @@ ShadowRenderer::~ShadowRenderer()
m_driver->removeTexture(shadowMapClientMapFuture);
}
+void ShadowRenderer::disable()
+{
+ m_shadows_enabled = false;
+ if (shadowMapTextureFinal) {
+ m_driver->setRenderTarget(shadowMapTextureFinal, true, true,
+ video::SColor(255, 255, 255, 255));
+ m_driver->setRenderTarget(0, true, true);
+ }
+}
+
void ShadowRenderer::initialize()
{
auto *gpu = m_driver->getGPUProgrammingServices();
// we need glsl
- if (m_shadows_enabled && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) {
+ if (m_shadows_supported && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) {
createShaders();
} else {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
warningstream << "Shadows: GLSL Shader not supported on this system."
<< std::endl;
@@ -94,6 +112,8 @@ void ShadowRenderer::initialize()
m_texture_format_color = m_shadow_map_texture_32bit
? video::ECOLOR_FORMAT::ECF_G32R32F
: video::ECOLOR_FORMAT::ECF_G16R16F;
+
+ m_shadows_enabled &= m_shadows_supported;
}
@@ -124,6 +144,16 @@ f32 ShadowRenderer::getMaxShadowFar() const
return 0.0f;
}
+void ShadowRenderer::setShadowIntensity(float shadow_intensity)
+{
+ m_shadow_strength = pow(shadow_intensity, 1.0f / m_shadow_strength_gamma);
+ if (m_shadow_strength > 1E-2)
+ enable();
+ else
+ disable();
+}
+
+
void ShadowRenderer::addNodeToShadowList(
scene::ISceneNode *node, E_SHADOW_MODE shadowMode)
{
@@ -153,6 +183,7 @@ void ShadowRenderer::updateSMTextures()
shadowMapTextureDynamicObjects = getSMTexture(
std::string("shadow_dynamic_") + itos(m_shadow_map_texture_size),
m_texture_format, true);
+ assert(shadowMapTextureDynamicObjects != nullptr);
}
if (!shadowMapClientMap) {
@@ -161,6 +192,7 @@ void ShadowRenderer::updateSMTextures()
std::string("shadow_clientmap_") + itos(m_shadow_map_texture_size),
m_shadow_map_colored ? m_texture_format_color : m_texture_format,
true);
+ assert(shadowMapClientMap != nullptr);
}
if (!shadowMapClientMapFuture && m_map_shadow_update_frames > 1) {
@@ -168,6 +200,7 @@ void ShadowRenderer::updateSMTextures()
std::string("shadow_clientmap_bb_") + itos(m_shadow_map_texture_size),
m_shadow_map_colored ? m_texture_format_color : m_texture_format,
true);
+ assert(shadowMapClientMapFuture != nullptr);
}
if (m_shadow_map_colored && !shadowMapTextureColors) {
@@ -175,6 +208,7 @@ void ShadowRenderer::updateSMTextures()
std::string("shadow_colored_") + itos(m_shadow_map_texture_size),
m_shadow_map_colored ? m_texture_format_color : m_texture_format,
true);
+ assert(shadowMapTextureColors != nullptr);
}
// The merge all shadowmaps texture
@@ -194,6 +228,7 @@ void ShadowRenderer::updateSMTextures()
shadowMapTextureFinal = getSMTexture(
std::string("shadowmap_final_") + itos(m_shadow_map_texture_size),
frt, true);
+ assert(shadowMapTextureFinal != nullptr);
}
if (!m_shadow_node_array.empty() && !m_light_list.empty()) {
@@ -270,6 +305,10 @@ void ShadowRenderer::update(video::ITexture *outputTarget)
updateSMTextures();
+ if (shadowMapTextureFinal == nullptr) {
+ return;
+ }
+
if (!m_shadow_node_array.empty() && !m_light_list.empty()) {
for (DirectionalLight &light : m_light_list) {
@@ -307,19 +346,23 @@ void ShadowRenderer::drawDebug()
/* this code just shows shadows textures in screen and in ONLY for debugging*/
#if 0
// this is debug, ignore for now.
- m_driver->draw2DImage(shadowMapTextureFinal,
- core::rect<s32>(0, 50, 128, 128 + 50),
- core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
+ if (shadowMapTextureFinal)
+ m_driver->draw2DImage(shadowMapTextureFinal,
+ core::rect<s32>(0, 50, 128, 128 + 50),
+ core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
- m_driver->draw2DImage(shadowMapClientMap,
- core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128),
- core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
- m_driver->draw2DImage(shadowMapTextureDynamicObjects,
- core::rect<s32>(0, 128 + 50 + 128, 128,
- 128 + 50 + 128 + 128),
- core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize()));
+ if (shadowMapClientMap)
+ m_driver->draw2DImage(shadowMapClientMap,
+ core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128),
+ core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
+
+ if (shadowMapTextureDynamicObjects)
+ m_driver->draw2DImage(shadowMapTextureDynamicObjects,
+ core::rect<s32>(0, 128 + 50 + 128, 128,
+ 128 + 50 + 128 + 128),
+ core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize()));
- if (m_shadow_map_colored) {
+ if (m_shadow_map_colored && shadowMapTextureColors) {
m_driver->draw2DImage(shadowMapTextureColors,
core::rect<s32>(128,128 + 50 + 128 + 128,
@@ -469,13 +512,13 @@ void ShadowRenderer::createShaders()
if (depth_shader == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl");
if (depth_shader_vs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl");
if (depth_shader_fs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
@@ -490,7 +533,7 @@ void ShadowRenderer::createShaders()
if (depth_shader == -1) {
// upsi, something went wrong loading shader.
delete m_shadow_depth_cb;
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling shadow mapping shader." << std::endl;
return;
}
@@ -506,13 +549,13 @@ void ShadowRenderer::createShaders()
if (depth_shader_entities == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl");
if (depth_shader_vs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl");
if (depth_shader_fs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
@@ -525,7 +568,7 @@ void ShadowRenderer::createShaders()
if (depth_shader_entities == -1) {
// upsi, something went wrong loading shader.
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling shadow mapping shader (dynamic)." << std::endl;
return;
}
@@ -539,14 +582,14 @@ void ShadowRenderer::createShaders()
if (mixcsm_shader == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass2_vertex.glsl");
if (depth_shader_vs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error cascade shadow mapping fs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass2_fragment.glsl");
if (depth_shader_fs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error cascade shadow mapping fs shader not found." << std::endl;
return;
}
@@ -565,7 +608,7 @@ void ShadowRenderer::createShaders()
// upsi, something went wrong loading shader.
delete m_shadow_mix_cb;
delete m_screen_quad;
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling cascade shadow mapping shader." << std::endl;
return;
}
@@ -579,13 +622,13 @@ void ShadowRenderer::createShaders()
if (m_shadow_map_colored && depth_shader_trans == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_trans_vertex.glsl");
if (depth_shader_vs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_trans_fragment.glsl");
if (depth_shader_fs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
@@ -601,7 +644,7 @@ void ShadowRenderer::createShaders()
// upsi, something went wrong loading shader.
delete m_shadow_depth_trans_cb;
m_shadow_map_colored = false;
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling colored shadow mapping shader." << std::endl;
return;
}
diff --git a/src/client/shadows/dynamicshadowsrender.h b/src/client/shadows/dynamicshadowsrender.h
index e4b3c3e22..dc8f79c56 100644
--- a/src/client/shadows/dynamicshadowsrender.h
+++ b/src/client/shadows/dynamicshadowsrender.h
@@ -82,11 +82,12 @@ public:
}
- bool is_active() const { return m_shadows_enabled; }
+ bool is_active() const { return m_shadows_enabled && shadowMapTextureFinal != nullptr; }
void setTimeOfDay(float isDay) { m_time_day = isDay; };
+ void setShadowIntensity(float shadow_intensity);
s32 getShadowSamples() const { return m_shadow_samples; }
- float getShadowStrength() const { return m_shadow_strength; }
+ float getShadowStrength() const { return m_shadows_enabled ? m_shadow_strength : 0.0f; }
float getTimeOfDay() const { return m_time_day; }
private:
@@ -101,6 +102,9 @@ private:
void mixShadowsQuad();
void updateSMTextures();
+ void disable();
+ void enable() { m_shadows_enabled = m_shadows_supported; }
+
// a bunch of variables
IrrlichtDevice *m_device{nullptr};
scene::ISceneManager *m_smgr{nullptr};
@@ -116,12 +120,14 @@ private:
std::vector<NodeToApply> m_shadow_node_array;
float m_shadow_strength;
+ float m_shadow_strength_gamma;
float m_shadow_map_max_distance;
float m_shadow_map_texture_size;
float m_time_day{0.0f};
int m_shadow_samples;
bool m_shadow_map_texture_32bit;
bool m_shadows_enabled;
+ bool m_shadows_supported;
bool m_shadow_map_colored;
u8 m_map_shadow_update_frames; /* Use this number of frames to update map shaodw */
u8 m_current_frame{0}; /* Current frame */
diff --git a/src/client/sky.h b/src/client/sky.h
index 3dc057b70..e03683f12 100644
--- a/src/client/sky.h
+++ b/src/client/sky.h
@@ -65,6 +65,7 @@ public:
}
void setSunVisible(bool sun_visible) { m_sun_params.visible = sun_visible; }
+ bool getSunVisible() const { return m_sun_params.visible; }
void setSunTexture(const std::string &sun_texture,
const std::string &sun_tonemap, ITextureSource *tsrc);
void setSunScale(f32 sun_scale) { m_sun_params.scale = sun_scale; }
@@ -72,6 +73,7 @@ public:
void setSunriseTexture(const std::string &sunglow_texture, ITextureSource* tsrc);
void setMoonVisible(bool moon_visible) { m_moon_params.visible = moon_visible; }
+ bool getMoonVisible() const { return m_moon_params.visible; }
void setMoonTexture(const std::string &moon_texture,
const std::string &moon_tonemap, ITextureSource *tsrc);
void setMoonScale(f32 moon_scale) { m_moon_params.scale = moon_scale; }
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index b935c0e21..2e9a19199 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -266,7 +266,7 @@ void set_default_settings()
// Effects Shadows
settings->setDefault("enable_dynamic_shadows", "false");
- settings->setDefault("shadow_strength", "0.2");
+ settings->setDefault("shadow_strength_gamma", "1.0");
settings->setDefault("shadow_map_max_distance", "200.0");
settings->setDefault("shadow_map_texture_size", "2048");
settings->setDefault("shadow_map_texture_32bit", "true");
diff --git a/src/lighting.h b/src/lighting.h
new file mode 100644
index 000000000..e0d9cee09
--- /dev/null
+++ b/src/lighting.h
@@ -0,0 +1,27 @@
+/*
+Minetest
+Copyright (C) 2021 x2048, Dmitry Kostenko <codeforsmile@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+/** Describes ambient light settings for a player
+ */
+struct Lighting
+{
+ float shadow_intensity {0.0f};
+};
diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp
index a98a5e7d1..6a78b4652 100644
--- a/src/network/clientopcodes.cpp
+++ b/src/network/clientopcodes.cpp
@@ -123,6 +123,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
{ "TOCLIENT_SRP_BYTES_S_B", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_SrpBytesSandB }, // 0x60
{ "TOCLIENT_FORMSPEC_PREPEND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FormspecPrepend }, // 0x61,
{ "TOCLIENT_MINIMAP_MODES", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MinimapModes }, // 0x62,
+ { "TOCLIENT_SET_LIGHTING", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_SetLighting }, // 0x63,
};
const static ServerCommandFactory null_command_factory = { "TOSERVER_NULL", 0, false };
diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp
index 48ad60ac6..15b576640 100644
--- a/src/network/clientpackethandler.cpp
+++ b/src/network/clientpackethandler.cpp
@@ -1682,3 +1682,11 @@ void Client::handleCommand_MinimapModes(NetworkPacket *pkt)
if (m_minimap)
m_minimap->setModeIndex(mode);
}
+
+void Client::handleCommand_SetLighting(NetworkPacket *pkt)
+{
+ Lighting& lighting = m_env.getLocalPlayer()->getLighting();
+
+ if (pkt->getRemainingBytes() >= 4)
+ *pkt >> lighting.shadow_intensity;
+}
diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h
index a5ff53216..f98a829ba 100644
--- a/src/network/networkprotocol.h
+++ b/src/network/networkprotocol.h
@@ -762,7 +762,12 @@ enum ToClientCommand
std::string extra
*/
- TOCLIENT_NUM_MSG_TYPES = 0x63,
+ TOCLIENT_SET_LIGHTING = 0x63,
+ /*
+ f32 shadow_intensity
+ */
+
+ TOCLIENT_NUM_MSG_TYPES = 0x64,
};
enum ToServerCommand
diff --git a/src/remoteplayer.h b/src/remoteplayer.h
index e33630841..0ab33adfe 100644
--- a/src/remoteplayer.h
+++ b/src/remoteplayer.h
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "player.h"
#include "skyparams.h"
+#include "lighting.h"
class PlayerSAO;
@@ -125,6 +126,10 @@ public:
*frame_speed = local_animation_speed;
}
+ void setLighting(const Lighting &lighting) { m_lighting = lighting; }
+
+ const Lighting& getLighting() const { return m_lighting; }
+
void setDirty(bool dirty) { m_dirty = true; }
u16 protocol_version = 0;
@@ -160,5 +165,7 @@ private:
MoonParams m_moon_params;
StarParams m_star_params;
+ Lighting m_lighting;
+
session_t m_peer_id = PEER_ID_INEXISTENT;
};
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 1ed6b0d5c..6153a0399 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -2295,6 +2295,47 @@ int ObjectRef::l_set_minimap_modes(lua_State *L)
return 0;
}
+// set_lighting(self, lighting)
+int ObjectRef::l_set_lighting(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ ObjectRef *ref = checkobject(L, 1);
+ RemotePlayer *player = getplayer(ref);
+ if (player == nullptr)
+ return 0;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+ Lighting lighting = player->getLighting();
+ lua_getfield(L, 2, "shadows");
+ if (lua_istable(L, -1)) {
+ lighting.shadow_intensity = getfloatfield_default(L, -1, "intensity", lighting.shadow_intensity);
+ }
+ lua_pop(L, -1);
+
+ getServer(L)->setLighting(player, lighting);
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+// get_lighting(self)
+int ObjectRef::l_get_lighting(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ ObjectRef *ref = checkobject(L, 1);
+ RemotePlayer *player = getplayer(ref);
+ if (player == nullptr)
+ return 0;
+
+ const Lighting &lighting = player->getLighting();
+
+ lua_newtable(L); // result
+ lua_newtable(L); // "shadows"
+ lua_pushnumber(L, lighting.shadow_intensity);
+ lua_setfield(L, -2, "intensity");
+ lua_setfield(L, -2, "shadows");
+ return 1;
+}
+
ObjectRef::ObjectRef(ServerActiveObject *object):
m_object(object)
{}
@@ -2448,5 +2489,7 @@ luaL_Reg ObjectRef::methods[] = {
luamethod(ObjectRef, get_eye_offset),
luamethod(ObjectRef, send_mapblock),
luamethod(ObjectRef, set_minimap_modes),
+ luamethod(ObjectRef, set_lighting),
+ luamethod(ObjectRef, get_lighting),
{0,0}
};
diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h
index 084d40c05..3e4e6681a 100644
--- a/src/script/lua_api/l_object.h
+++ b/src/script/lua_api/l_object.h
@@ -376,4 +376,10 @@ private:
// set_minimap_modes(self, modes, wanted_mode)
static int l_set_minimap_modes(lua_State *L);
+
+ // set_lighting(self, lighting)
+ static int l_set_lighting(lua_State *L);
+
+ // get_lighting(self)
+ static int l_get_lighting(lua_State *L);
};
diff --git a/src/server.cpp b/src/server.cpp
index d9205c895..4bc049e32 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -1795,6 +1795,16 @@ void Server::SendOverrideDayNightRatio(session_t peer_id, bool do_override,
Send(&pkt);
}
+void Server::SendSetLighting(session_t peer_id, const Lighting &lighting)
+{
+ NetworkPacket pkt(TOCLIENT_SET_LIGHTING,
+ 4, peer_id);
+
+ pkt << lighting.shadow_intensity;
+
+ Send(&pkt);
+}
+
void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed)
{
NetworkPacket pkt(TOCLIENT_TIME_OF_DAY, 0, peer_id);
@@ -3386,6 +3396,13 @@ void Server::overrideDayNightRatio(RemotePlayer *player, bool do_override,
SendOverrideDayNightRatio(player->getPeerId(), do_override, ratio);
}
+void Server::setLighting(RemotePlayer *player, const Lighting &lighting)
+{
+ sanity_check(player);
+ player->setLighting(lighting);
+ SendSetLighting(player->getPeerId(), lighting);
+}
+
void Server::notifyPlayers(const std::wstring &msg)
{
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg));
diff --git a/src/server.h b/src/server.h
index 2741b3157..c05393291 100644
--- a/src/server.h
+++ b/src/server.h
@@ -69,6 +69,7 @@ struct SkyboxParams;
struct SunParams;
struct MoonParams;
struct StarParams;
+struct Lighting;
class ServerThread;
class ServerModManager;
class ServerInventoryManager;
@@ -333,6 +334,8 @@ public:
void overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness);
+ void setLighting(RemotePlayer *player, const Lighting &lighting);
+
/* con::PeerHandler implementation. */
void peerAdded(con::Peer *peer);
void deletingPeer(con::Peer *peer, bool timeout);
@@ -459,6 +462,7 @@ private:
void SendSetStars(session_t peer_id, const StarParams &params);
void SendCloudParams(session_t peer_id, const CloudParams &params);
void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio);
+ void SendSetLighting(session_t peer_id, const Lighting &lighting);
void broadcastModChannelMessage(const std::string &channel,
const std::string &message, session_t from_peer);