]> git.lizzy.rs Git - minetest.git/commitdiff
Add API to control shadow intensity from the game/mod (#11944)
authorx2048 <codeforsmile@gmail.com>
Sat, 26 Mar 2022 15:58:26 +0000 (16:58 +0100)
committerGitHub <noreply@github.com>
Sat, 26 Mar 2022 15:58:26 +0000 (16:58 +0100)
* Also Disable shadows when sun/moon is hidden. Fixes #11972.

24 files changed:
builtin/settingtypes.txt
client/shaders/nodes_shader/opengl_fragment.glsl
client/shaders/nodes_shader/opengl_vertex.glsl
client/shaders/object_shader/opengl_fragment.glsl
client/shaders/object_shader/opengl_vertex.glsl
doc/lua_api.txt
games/devtest/mods/experimental/init.lua
games/devtest/mods/experimental/lighting.lua [new file with mode: 0644]
src/client/client.h
src/client/game.cpp
src/client/localplayer.h
src/client/shadows/dynamicshadowsrender.cpp
src/client/shadows/dynamicshadowsrender.h
src/client/sky.h
src/defaultsettings.cpp
src/lighting.h [new file with mode: 0644]
src/network/clientopcodes.cpp
src/network/clientpackethandler.cpp
src/network/networkprotocol.h
src/remoteplayer.h
src/script/lua_api/l_object.cpp
src/script/lua_api/l_object.h
src/server.cpp
src/server.h

index ff2d72927c63e326341796b75c1765baa94fce3d..3dc165bd16aecae74a2105398bd8207028541de1 100644 (file)
@@ -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
index e5f5c703a17b1d6b0cc4e6bdc2553272febc8cb1..adc8adccb0b5efdade29cad7e62eb245bd404440 100644 (file)
@@ -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
index 95cd138a8791988b7c26b4e263e4c74d2977c9ff..5e77ac719fd477c8ce475ad33842cc9048e163e6 100644 (file)
@@ -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
-
 }
index fdfcec0c8928c0913b4c223f30f173955618ec2f..edb9d2bb1d6ed15b73b343b541937814a8e0a1ed 100644 (file)
@@ -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
index 185551c5837317417f47d683e64207423f36ae75..ff0067302fb73ec8c4aa327a4dfba311af1e7429 100644 (file)
@@ -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
 }
index 52da17e9c0d96964f3219e0d14eebba8bbf5a019..029c53616e2f20bcc095bcecf1d86b2275ec89c8 100644 (file)
@@ -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`
 -----------
index b292f792e3a0696f80535980e822265f777220cb..70091179c22a7e049d3f0d7bd440ebfe0bf2c1ba 100644 (file)
@@ -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 (file)
index 0000000..2b35055
--- /dev/null
@@ -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
index 84c85471daefd87fccabe924d9b27bd2172d3d79..0e29fdbe205ec11230a8046cc46b179693820bda 100644 (file)
@@ -227,6 +227,7 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
        void handleCommand_PlayerSpeed(NetworkPacket *pkt);
        void handleCommand_MediaPush(NetworkPacket *pkt);
        void handleCommand_MinimapModes(NetworkPacket *pkt);
+       void handleCommand_SetLighting(NetworkPacket *pkt);
 
        void ProcessData(NetworkPacket *pkt);
 
index 7450fb91c1e8b02b8a52e9b32b1fb859fd59bdb3..edc69dcc208ed3dd0f5a260a4ad7629cd166e614 100644 (file)
@@ -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);
index 577be28038ecb6c43b87572abade2c4fad051e2a..3d0072fc1110f025607b4786db416db1c973fc30 100644 (file)
@@ -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 @@ class LocalPlayer : public Player
                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 @@ class LocalPlayer : public Player
 
        GenericCAO *m_cao = nullptr;
        Client *m_client;
+       Lighting m_lighting;
 };
index 528415aafd39bd925ddbe4acd879954508155c25..24adb21e2c0cac9bb6a293013ed1ab4c502d6238 100644 (file)
@@ -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;
                }
index e4b3c3e220e213bc74bd9576a9b79d07d2d3162b..dc8f79c567eef9c316efee8876cd490ce02cc4e8 100644 (file)
@@ -82,11 +82,12 @@ class ShadowRenderer
        }
 
 
-       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 @@ class ShadowRenderer
        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 @@ class ShadowRenderer
        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 */
index 3dc057b70890f72ab47c393cc2476bbfb89ff8dc..e03683f121a40a03c41689e12e3ac1ff50425df1 100644 (file)
@@ -65,6 +65,7 @@ class Sky : public scene::ISceneNode
        }
 
        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 @@ class Sky : public scene::ISceneNode
        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; }
index b935c0e219e0c3ed5f2a1891f173aa883ba467eb..2e9a191994c578a6ba53a5cc29a7147e192ae16e 100644 (file)
@@ -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 (file)
index 0000000..e0d9cee
--- /dev/null
@@ -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};
+};
index a98a5e7d187b00b0bc31d5d6aeec5534862c3a1e..6a78b4652e072fb030babce62acf3322176e7826 100644 (file)
@@ -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 };
index 48ad60ac6d1fec1dabf6a7deb2be7b1e8f213c0a..15b5766404d3a06b031ee988876745f656b7d490 100644 (file)
@@ -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;
+}
index a5ff532166edd2aaa46149c36a5b0f1dab75e9a1..f98a829ba68f4221b7db5edd9e11793003db8d73 100644 (file)
@@ -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
index e336308410c07e408236d377edd3870d80647bda..0ab33adfe18e3d0a815941e757eab5029f7c72fb 100644 (file)
@@ -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 @@ class RemotePlayer : public Player
                *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 @@ class RemotePlayer : public Player
        MoonParams m_moon_params;
        StarParams m_star_params;
 
+       Lighting m_lighting;
+
        session_t m_peer_id = PEER_ID_INEXISTENT;
 };
index 1ed6b0d5c9a7fa9d9ac94ea1874770e33c3964c5..6153a03996f3ca825e8cedee1fc9467b50a690c6 100644 (file)
@@ -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}
 };
index 084d40c05923aa83d94887bfe88ed5549730e6e6..3e4e6681a122b4b9ec80b7756b452dd133cfa971 100644 (file)
@@ -376,4 +376,10 @@ class ObjectRef : public ModApiBase {
 
        // 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);
 };
index d9205c89568b45c1022aa96e6c486c6b244b45b9..4bc049e320f1bd8812590175bccf0649f8bb0b8c 100644 (file)
@@ -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));
index 2741b31575606146a6a306a9de8ef03be8f6458a..c0539329163c3dcf063e77317dfbc734693e5c87 100644 (file)
@@ -69,6 +69,7 @@ struct SkyboxParams;
 struct SunParams;
 struct MoonParams;
 struct StarParams;
+struct Lighting;
 class ServerThread;
 class ServerModManager;
 class ServerInventoryManager;
@@ -333,6 +334,8 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 
        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 @@ class Server : public con::PeerHandler, public MapEventReceiver,
        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);