diff --git a/builtin/game/features.lua b/builtin/game/features.lua index 874d3e885..d04909861 100644 --- a/builtin/game/features.lua +++ b/builtin/game/features.lua @@ -39,6 +39,7 @@ core.features = { dynamic_add_media_filepath = true, lsystem_decoration_type = true, item_meta_range = true, + light_intensity = true, } function core.has_feature(arg) diff --git a/doc/lua_api.md b/doc/lua_api.md index 8a1df92ef..cdea22960 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5431,6 +5431,8 @@ Utilities lsystem_decoration_type = true, -- Overrideable pointing range using the itemstack meta key `"range"` (5.9.0) item_meta_range = true, + -- set_lighting support light_intensity table (5.9.0) + light_intensity = true, } ``` @@ -8336,6 +8338,18 @@ child will follow movement and rotation of that bone. * `volumetric_light`: is a table that controls volumetric light (a.k.a. "godrays") * `strength`: sets the strength of the volumetric light effect from 0 (off, default) to 1 (strongest) * This value has no effect on clients who have the "Volumetric Lighting" or "Bloom" shaders disabled. + * `light_intensity` is a table that controls calculation of sun light color. + `sun_color = color_offset + color_ratio_coef*daynight_ratio` where `daynight_ratio` is not linear to day time. + Result color lesser or equal to 0.0 means no color in light. + Result color greater or equal to 1.0 means full color in light. + * `color_offset` is a table that controls red, green and blue color offsets. + * `r` (default: `-0.04`) + * `g` (default: `-0.04`) + * `b` (default: `0.078`) + * `color_ratio_coef` is a table that controls red, green and blue color ration coefficients. + * `r` (default: `0.001`) + * `g` (default: `0.001`) + * `b` (default: `0.00098`) * `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`. diff --git a/games/devtest/mods/lighting/init.lua b/games/devtest/mods/lighting/init.lua index 7b4392fb8..8a21b458c 100644 --- a/games/devtest/mods/lighting/init.lua +++ b/games/devtest/mods/lighting/init.lua @@ -1,30 +1,15 @@ -local lighting_sections = { - {n = "shadows", d = "Shadows", - entries = { - { n = "intensity", d = "Shadow Intensity", min = 0, max = 1 } - } - }, - { - n = "exposure", d = "Exposure", - entries = { - {n = "luminance_min", d = "Minimum Luminance", min = -10, max = 10}, - {n = "luminance_max", d = "Maximum Luminance", min = -10, max = 10}, - {n = "exposure_correction", d = "Exposure Correction", min = -10, max = 10}, - {n = "speed_dark_bright", d = "Bright light adaptation speed", min = -10, max = 10, type="log2"}, - {n = "speed_bright_dark", d = "Dark scene adaptation speed", min = -10, max = 10, type="log2"}, - {n = "center_weight_power", d = "Power factor for center-weighting", min = 0.1, max = 10}, - } - } -} -local function dump_lighting(lighting) +local modpath = minetest.get_modpath(minetest.get_current_modname()) + + +local function dumpByRecipe(data, recipe) local result = "{\n" local section_count = 0 - for _,section in ipairs(lighting_sections) do + for _,section in ipairs(recipe) do section_count = section_count + 1 local parameters = section.entries or {} - local state = lighting[section.n] or {} + local state = data[section.n] or {} result = result.." "..section.n.." = {\n" @@ -40,7 +25,7 @@ local function dump_lighting(lighting) result = result.." }" - if section_count < #lighting_sections then + if section_count < #recipe then result = result.."," end result = result.."\n" @@ -49,74 +34,59 @@ local function dump_lighting(lighting) return result end -minetest.register_chatcommand("set_lighting", { - params = "", - description = "Tune lighting parameters", - func = function(player_name, param) - local player = minetest.get_player_by_name(player_name); - if not player then return end +local function buildGUI(player, data, recipe, gui_name) + local form = { + "formspec_version[2]", + "size[15,30]", + "position[0.99,0.15]", + "anchor[1,0]", + "padding[0.05,0.1]", + "no_prepend[]" + }; - local lighting = player:get_lighting() - local exposure = lighting.exposure or {} + local line = 1 + for _,section in ipairs(recipe) do + local parameters = section.entries or {} + local state = data[section.n] or {} - local form = { - "formspec_version[2]", - "size[15,30]", - "position[0.99,0.15]", - "anchor[1,0]", - "padding[0.05,0.1]", - "no_prepend[]" - }; + table.insert(form, "label[1,"..line..";"..section.d.."]") + line = line + 1 - local line = 1 - for _,section in ipairs(lighting_sections) do - local parameters = section.entries or {} - local state = lighting[section.n] or {} - - table.insert(form, "label[1,"..line..";"..section.d.."]") - line = line + 1 - - for _,v in ipairs(parameters) do - table.insert(form, "label[2,"..line..";"..v.d.."]") - table.insert(form, "scrollbaroptions[min=0;max=1000;smallstep=10;largestep=100;thumbsize=10]") - local value = state[v.n] - if v.type == "log2" then - value = math.log(value or 1) / math.log(2) - end - local sb_scale = math.floor(1000 * (math.max(v.min, value or 0) - v.min) / (v.max - v.min)) - table.insert(form, "scrollbar[2,"..(line+0.7)..";12,1;horizontal;"..section.n.."."..v.n..";"..sb_scale.."]") - line = line + 2.7 + for _,v in ipairs(parameters) do + table.insert(form, "label[2,"..line..";"..v.d.."]") + table.insert(form, "scrollbaroptions[min=0;max=1000;smallstep=10;largestep=100;thumbsize=10]") + local value = state[v.n] + if v.type == "log2" then + value = math.log(value or 1) / math.log(2) end - - line = line + 1 + local sb_scale = math.floor(1000 * (math.max(v.min, value or 0) - v.min) / (v.max - v.min)) + table.insert(form, "scrollbar[2,"..(line+0.7)..";12,1;horizontal;"..section.n.."."..v.n..";"..sb_scale.."]") + line = line + 2.7 end - minetest.show_formspec(player_name, "lighting", table.concat(form)) - local debug_value = dump_lighting(lighting) - local debug_ui = player:hud_add({type="text", position={x=0.1, y=0.3}, scale={x=1,y=1}, alignment = {x=1, y=1}, text=debug_value, number=0xFFFFFF}) - player:get_meta():set_int("lighting_hud", debug_ui) + line = line + 1 end -}) -minetest.register_on_player_receive_fields(function(player, formname, fields) - if formname ~= "lighting" then return end + minetest.show_formspec(player:get_player_name(), gui_name, table.concat(form)) + local debug_value = dumpByRecipe(data, recipe) + local debug_ui = player:hud_add({type="text", position={x=0.1, y=0.3}, scale={x=1,y=1}, alignment = {x=1, y=1}, text=debug_value, number=0xFFFFFF}) + player:get_meta():set_int(gui_name.."_hud", debug_ui) +end - if not player then return end - - local hud_id = player:get_meta():get_int("lighting_hud") +local function receiveFields(player, fields, data, recipe, gui_name) + local hud_id = player:get_meta():get_int(gui_name.."_hud") if fields.quit then player:hud_remove(hud_id) - player:get_meta():set_int("lighting_hud", -1) + player:get_meta():set_int(gui_name.."_hud", -1) return end - local lighting = player:get_lighting() - for _,section in ipairs(lighting_sections) do + for _,section in ipairs(recipe) do local parameters = section.entries or {} - local state = (lighting[section.n] or {}) - lighting[section.n] = state + local state = (data[section.n] or {}) + data[section.n] = state for _,v in ipairs(parameters) do @@ -133,8 +103,96 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end end - local debug_value = dump_lighting(lighting) + local debug_value = dumpByRecipe(data, recipe) player:hud_change(hud_id, "text", debug_value) +end + +local lighting_recipe = { + {n = "shadows", d = "Shadows", + entries = { + { n = "intensity", d = "Shadow Intensity", min = 0, max = 1 } + } + }, + { + n = "exposure", d = "Exposure", + entries = { + {n = "luminance_min", d = "Minimum Luminance", min = -10, max = 10}, + {n = "luminance_max", d = "Maximum Luminance", min = -10, max = 10}, + {n = "exposure_correction", d = "Exposure Correction", min = -10, max = 10}, + {n = "speed_dark_bright", d = "Bright light adaptation speed", min = -10, max = 10, type="log2"}, + {n = "speed_bright_dark", d = "Dark scene adaptation speed", min = -10, max = 10, type="log2"}, + {n = "center_weight_power", d = "Power factor for center-weighting", min = 0.1, max = 10}, + } + }, +} + +minetest.register_chatcommand("set_lighting", { + params = "", + description = "Tune lighting parameters", + func = function(player_name, param) + local player = minetest.get_player_by_name(player_name) + if not player then return end + + local lighting = player:get_lighting() + + buildGUI(player, lighting, lighting_recipe, "lighting") + end +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "lighting" then return end + + if not player then return end + + local lighting = player:get_lighting() + + receiveFields(player, fields, lighting, lighting_recipe, "lighting") player:set_lighting(lighting) -end) \ No newline at end of file +end) + +local light_intensity_recipe = { + {n = "color_offset", d = "Color offset", + entries = { + {n = "r", d = "Red color offset", min = -1, max = 2}, + {n = "g", d = "Green color offset", min = -1, max = 2}, + {n = "b", d = "Blue color offset", min = -1, max = 2}, + } + }, + {n = "color_ratio_coef", d = "Color day-night ratio coefficient", + entries = { + {n = "r", d = "Red color day-night ratio coefficient", min = -1e-3, max = 2e-3}, + {n = "g", d = "Green color day-night ratio coefficient", min = -1e-3, max = 2e-3}, + {n = "b", d = "Blue color day-night ratio coefficient", min = -1e-3, max = 2e-3}, + } + } +} + + +minetest.register_chatcommand("set_light_intensity", { + params = "", + description = "Tune lighting light_intensity parameters", + func = function(player_name, param) + local player = minetest.get_player_by_name(player_name) + if not player then return end + + local lighting = player:get_lighting() + local light_intensity = lighting.light_intensity + + buildGUI(player, light_intensity, light_intensity_recipe, "light_intensity") + end +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "light_intensity" then return end + + if not player then return end + + local lighting = player:get_lighting() + local light_intensity = lighting.light_intensity + + receiveFields(player, fields, light_intensity, light_intensity_recipe, "light_intensity") + + player:set_lighting(lighting) +end) + diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index 7e1676ffe..9f02d1cc7 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -262,7 +262,8 @@ void ClientEnvironment::step(float dtime) u16 light = getInteriorLight(node_at_lplayer, 0, m_client->ndef()); lplayer->light_color = encode_light(light, 0); // this transfers light.alpha - final_color_blend(&lplayer->light_color, light, day_night_ratio); + const LightIntensity &lightIntensity = m_client->getEnv().getLocalPlayer()->getLighting().lightIntensity; + final_color_blend(&lplayer->light_color, light, day_night_ratio, lightIntensity); } /* diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index 45995c0ea..e353380f2 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -719,6 +719,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) const float animation_time = m_client->getAnimationTime(); const int crack = m_client->getCrackLevel(); const u32 daynight_ratio = m_client->getEnv().getDayNightRatio(); + const Lighting &lighting = m_client->getEnv().getLocalPlayer()->getLighting(); const v3f camera_position = m_camera_position; @@ -780,7 +781,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) mesh_animate_count < (m_control.range_all ? 200 : 50)) { bool animated = block_mesh->animate(faraway, animation_time, - crack, daynight_ratio); + crack, daynight_ratio, lighting.lightIntensity); if (animated) mesh_animate_count++; } else { diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 9fb110fdc..849bbdfbc 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -908,8 +908,10 @@ void GenericCAO::updateLight(u32 day_night_ratio) // based on the entity glow. if (m_enable_shaders) light = encode_light(light_at_pos, m_prop.glow); - else - final_color_blend(&light, light_at_pos, day_night_ratio); + else { + const LightIntensity &lightIntensity = m_env->getLocalPlayer()->getLighting().lightIntensity; + final_color_blend(&light, light_at_pos, day_night_ratio, lightIntensity); + } if (light != m_last_light) { m_last_light = light; diff --git a/src/client/game.cpp b/src/client/game.cpp index 84b2815c8..261fc2cc1 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -470,8 +470,9 @@ public: void onSetConstants(video::IMaterialRendererServices *services) override { u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio(); + const auto &lighting = m_client->getEnv().getLocalPlayer()->getLighting(); video::SColorf sunlight; - get_sunlight_color(&sunlight, daynight_ratio); + get_sunlight_color(&sunlight, daynight_ratio, lighting.lightIntensity); m_day_light.set(sunlight, services); u32 animation_timer = m_client->getEnv().getFrameTime() % 1000000; @@ -509,7 +510,7 @@ public: m_texel_size0_vertex.set(m_texel_size0, services); m_texel_size0_pixel.set(m_texel_size0, services); - const AutoExposure &exposure_params = m_client->getEnv().getLocalPlayer()->getLighting().exposure; + const AutoExposure &exposure_params = lighting.exposure; std::array exposure_buffer = { std::pow(2.0f, exposure_params.luminance_min), std::pow(2.0f, exposure_params.luminance_max), @@ -527,7 +528,6 @@ public: m_bloom_strength_pixel.set(&m_bloom_strength, services); } - const auto &lighting = m_client->getEnv().getLocalPlayer()->getLighting(); float saturation = lighting.saturation; m_saturation_pixel.set(&saturation, services); @@ -3458,8 +3458,9 @@ PointedThing Game::updatePointedThing( } u32 daynight_ratio = client->getEnv().getDayNightRatio(); + const Lighting &lighting = client->getEnv().getLocalPlayer()->getLighting(); video::SColor c; - final_color_blend(&c, light_level, daynight_ratio); + final_color_blend(&c, light_level, daynight_ratio, lighting.lightIntensity); // Modify final color a bit with time u32 timer = client->getEnv().getFrameTime() % 5000; diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index 1d74b70cb..04aa50767 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/directiontables.h" #include "client/meshgen/collector.h" #include "client/renderingengine.h" +#include "client/localplayer.h" #include #include #include @@ -281,19 +282,17 @@ u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData return getSmoothLightCombined(p, dirs, data); } -void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio){ - f32 rg = daynight_ratio / 1000.0f - 0.04f; - f32 b = (0.98f * daynight_ratio) / 1000.0f + 0.078f; - sunlight->r = rg; - sunlight->g = rg; - sunlight->b = b; +void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio, const LightIntensity &lightIntensity){ + sunlight->r = lightIntensity.colorOffset_rgb.X+lightIntensity.colorRatioCoef_rgb.X*daynight_ratio; + sunlight->g = lightIntensity.colorOffset_rgb.Y+lightIntensity.colorRatioCoef_rgb.Y*daynight_ratio; + sunlight->b = lightIntensity.colorOffset_rgb.Z+lightIntensity.colorRatioCoef_rgb.Z*daynight_ratio; } void final_color_blend(video::SColor *result, - u16 light, u32 daynight_ratio) + u16 light, u32 daynight_ratio, const LightIntensity &lightIntensity) { video::SColorf dayLight; - get_sunlight_color(&dayLight, daynight_ratio); + get_sunlight_color(&dayLight, daynight_ratio, lightIntensity); final_color_blend(result, encode_light(light, 0), dayLight); } @@ -742,8 +741,9 @@ MapBlockMesh::MapBlockMesh(Client *client, MeshMakeData *data, v3s16 camera_offs if (!m_enable_shaders) { // Extract colors for day-night animation // Dummy sunlight to handle non-sunlit areas + const LightIntensity &lightIntensity = client->getEnv().getLocalPlayer()->getLighting().lightIntensity; video::SColorf sunlight; - get_sunlight_color(&sunlight, 0); + get_sunlight_color(&sunlight, 0, lightIntensity); std::map colors; const u32 vertex_count = p.vertices.size(); @@ -834,7 +834,7 @@ MapBlockMesh::~MapBlockMesh() } bool MapBlockMesh::animate(bool faraway, float time, int crack, - u32 daynight_ratio) + u32 daynight_ratio, const LightIntensity &lightIntensity) { if (!m_has_animation) { m_animation_force_timer = 100000; @@ -896,7 +896,7 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, // Day-night transition if (!m_enable_shaders && (daynight_ratio != m_last_daynight_ratio)) { video::SColorf day_color; - get_sunlight_color(&day_color, daynight_ratio); + get_sunlight_color(&day_color, daynight_ratio, lightIntensity); for (auto &daynight_diff : m_daynight_diffs) { auto *mesh = m_mesh[daynight_diff.first.first]; diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h index 7cd368762..5065dab48 100644 --- a/src/client/mapblock_mesh.h +++ b/src/client/mapblock_mesh.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/numeric.h" #include "client/tile.h" #include "voxel.h" +#include "lighting.h" #include #include #include @@ -190,7 +191,7 @@ public: // daynight_ratio: 0 .. 1000 // crack: -1 .. CRACK_ANIMATION_LENGTH-1 (-1 for off) // Returns true if anything has been changed. - bool animate(bool faraway, float time, int crack, u32 daynight_ratio); + bool animate(bool faraway, float time, int crack, u32 daynight_ratio, const LightIntensity &lightIntensity); scene::IMesh *getMesh() { @@ -308,7 +309,7 @@ u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData * Returns the sunlight's color from the current * day-night ratio. */ -void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio); +void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio, const LightIntensity &lightIntensity); /*! * Gives the final SColor shown on screen. @@ -318,7 +319,7 @@ void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio); * night light */ void final_color_blend(video::SColor *result, - u16 light, u32 daynight_ratio); + u16 light, u32 daynight_ratio, const LightIntensity &lightIntensity); /*! * Gives the final SColor shown on screen. diff --git a/src/lighting.cpp b/src/lighting.cpp index 0af1eb86e..30c291ca5 100644 --- a/src/lighting.cpp +++ b/src/lighting.cpp @@ -27,3 +27,8 @@ AutoExposure::AutoExposure() speed_bright_dark(1000.f), center_weight_power(1.f) {} + +LightIntensity::LightIntensity() + : colorOffset_rgb{-0.04, -0.04, 0.078}, + colorRatioCoef_rgb{1e-3, 1e-3, 0.98e-3} +{} diff --git a/src/lighting.h b/src/lighting.h index 262a48b5d..2477e3592 100644 --- a/src/lighting.h +++ b/src/lighting.h @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once +#include "irr_v3d.h" /** * Parameters for automatic exposure compensation @@ -46,11 +47,33 @@ struct AutoExposure AutoExposure(); }; +/** + * Parameters for set color and intensity of night and day light. + * + * Light color is calculated in function get_sunlight_color. + * Variable daynight_ration can be from 0 to 1000. + * + * sunlight->r = colorOffset_rgb.X+colorRatioCoef_rgb.X*daynight_ratio; + * sunlight->g = colorOffset_rgb.Y+colorRatioCoef_rgb.Y*daynight_ratio; + * sunlight->b = colorOffset_rgb.Z+colorRatioCoef_rgb.Z*daynight_ratio; + * + */ +struct LightIntensity +{ + /// @brief Sunlight color offset + v3f colorOffset_rgb; + /// @brief Sunlight color dayratio effect + v3f colorRatioCoef_rgb; + + LightIntensity(); +}; + /** Describes ambient light settings for a player */ struct Lighting { AutoExposure exposure; + LightIntensity lightIntensity; float shadow_intensity {0.0f}; float saturation {1.0f}; float volumetric_light_strength {0.0f}; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 90f2bed5b..c34d34acb 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1815,4 +1815,12 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt) } if (pkt->getRemainingBytes() >= 4) *pkt >> lighting.volumetric_light_strength; + if (pkt->getRemainingBytes() >= 24) { + *pkt >> lighting.lightIntensity.colorOffset_rgb.X + >> lighting.lightIntensity.colorOffset_rgb.Y + >> lighting.lightIntensity.colorOffset_rgb.Z + >> lighting.lightIntensity.colorRatioCoef_rgb.X + >> lighting.lightIntensity.colorRatioCoef_rgb.Y + >> lighting.lightIntensity.colorRatioCoef_rgb.Z; + } } diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index ad4b7af41..0182d67f1 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -2526,7 +2526,7 @@ int ObjectRef::l_set_lighting(lua_State *L) if (lua_istable(L, -1)) { lighting.exposure.luminance_min = getfloatfield_default(L, -1, "luminance_min", lighting.exposure.luminance_min); lighting.exposure.luminance_max = getfloatfield_default(L, -1, "luminance_max", lighting.exposure.luminance_max); - lighting.exposure.exposure_correction = getfloatfield_default(L, -1, "exposure_correction", lighting.exposure.exposure_correction); + lighting.exposure.exposure_correction = getfloatfield_default(L, -1, "exposure_correction", lighting.exposure.exposure_correction); lighting.exposure.speed_dark_bright = getfloatfield_default(L, -1, "speed_dark_bright", lighting.exposure.speed_dark_bright); lighting.exposure.speed_bright_dark = getfloatfield_default(L, -1, "speed_bright_dark", lighting.exposure.speed_bright_dark); lighting.exposure.center_weight_power = getfloatfield_default(L, -1, "center_weight_power", lighting.exposure.center_weight_power); @@ -2539,7 +2539,26 @@ int ObjectRef::l_set_lighting(lua_State *L) lighting.volumetric_light_strength = rangelim(lighting.volumetric_light_strength, 0.0f, 1.0f); } lua_pop(L, 1); // volumetric_light -} + + lua_getfield(L, 2, "light_intensity"); + if (lua_istable(L, -1)) { + lua_getfield(L, 3, "color_offset"); + if (lua_istable(L, -1)) { + lighting.lightIntensity.colorOffset_rgb.X = getfloatfield_default(L, -1, "r", lighting.lightIntensity.colorOffset_rgb.X); + lighting.lightIntensity.colorOffset_rgb.Y = getfloatfield_default(L, -1, "g", lighting.lightIntensity.colorOffset_rgb.Y); + lighting.lightIntensity.colorOffset_rgb.Z = getfloatfield_default(L, -1, "b", lighting.lightIntensity.colorOffset_rgb.Z); + } + lua_pop(L, 1); // color_offset + lua_getfield(L, 3, "color_ratio_coef"); + if (lua_istable(L, -1)) { + lighting.lightIntensity.colorRatioCoef_rgb.X = getfloatfield_default(L, -1, "r", lighting.lightIntensity.colorRatioCoef_rgb.X); + lighting.lightIntensity.colorRatioCoef_rgb.Y = getfloatfield_default(L, -1, "g", lighting.lightIntensity.colorRatioCoef_rgb.Y); + lighting.lightIntensity.colorRatioCoef_rgb.Z = getfloatfield_default(L, -1, "b", lighting.lightIntensity.colorRatioCoef_rgb.Z); + } + lua_pop(L, 1); // color_ratio_coef + } + lua_pop(L, 1); // light_intensity + } getServer(L)->setLighting(player, lighting); return 0; @@ -2581,6 +2600,24 @@ int ObjectRef::l_get_lighting(lua_State *L) lua_pushnumber(L, lighting.volumetric_light_strength); lua_setfield(L, -2, "strength"); lua_setfield(L, -2, "volumetric_light"); + lua_newtable(L); // "light_intensity" + lua_newtable(L); // "color_offset" + lua_pushnumber(L, lighting.lightIntensity.colorOffset_rgb.X); + lua_setfield(L, -2, "r"); + lua_pushnumber(L, lighting.lightIntensity.colorOffset_rgb.Y); + lua_setfield(L, -2, "g"); + lua_pushnumber(L, lighting.lightIntensity.colorOffset_rgb.Z); + lua_setfield(L, -2, "b"); + lua_setfield(L, -2, "color_offset"); + lua_newtable(L); // "color_ratio_coef" + lua_pushnumber(L, lighting.lightIntensity.colorRatioCoef_rgb.X); + lua_setfield(L, -2, "r"); + lua_pushnumber(L, lighting.lightIntensity.colorRatioCoef_rgb.Y); + lua_setfield(L, -2, "g"); + lua_pushnumber(L, lighting.lightIntensity.colorRatioCoef_rgb.Z); + lua_setfield(L, -2, "b"); + lua_setfield(L, -2, "color_ratio_coef"); + lua_setfield(L, -2, "light_intensity"); return 1; } diff --git a/src/server.cpp b/src/server.cpp index 5dd2d4691..05b4ed469 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1894,9 +1894,16 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting) << lighting.exposure.speed_dark_bright << lighting.exposure.speed_bright_dark << lighting.exposure.center_weight_power; - + pkt << lighting.volumetric_light_strength; + pkt << lighting.lightIntensity.colorOffset_rgb.X + << lighting.lightIntensity.colorOffset_rgb.Y + << lighting.lightIntensity.colorOffset_rgb.Z + << lighting.lightIntensity.colorRatioCoef_rgb.X + << lighting.lightIntensity.colorRatioCoef_rgb.Y + << lighting.lightIntensity.colorRatioCoef_rgb.Z; + Send(&pkt); }