From 6ac4447134506b766de44b69a903b77e07853936 Mon Sep 17 00:00:00 2001 From: grorp Date: Wed, 9 Oct 2024 15:08:03 +0200 Subject: [PATCH] Make bloom parameters server-controlled (#15231) --- builtin/mainmenu/settings/dlg_settings.lua | 5 +++ builtin/settingtypes.txt | 22 ----------- doc/lua_api.md | 28 ++++++++++++-- games/devtest/mods/lighting/init.lua | 44 +++++++++++++++------- src/client/game.cpp | 31 +++++---------- src/client/renderingengine.cpp | 1 - src/client/renderingengine.h | 1 - src/defaultsettings.cpp | 3 -- src/lighting.h | 3 ++ src/network/clientpackethandler.cpp | 5 +++ src/script/lua_api/l_object.cpp | 16 ++++++++ src/server.cpp | 2 + 12 files changed, 95 insertions(+), 66 deletions(-) diff --git a/builtin/mainmenu/settings/dlg_settings.lua b/builtin/mainmenu/settings/dlg_settings.lua index 3da80e877..182319be0 100644 --- a/builtin/mainmenu/settings/dlg_settings.lua +++ b/builtin/mainmenu/settings/dlg_settings.lua @@ -161,6 +161,11 @@ local function load() note.requires = get_setting_info("enable_auto_exposure").requires table.insert(content, idx, note) + idx = table.indexof(content, "enable_bloom") + 1 + note = component_funcs.note(fgettext_ne("(The game will need to enable bloom as well)")) + note.requires = get_setting_info("enable_bloom").requires + table.insert(content, idx, note) + idx = table.indexof(content, "enable_volumetric_lighting") + 1 note = component_funcs.note(fgettext_ne("(The game will need to enable volumetric lighting as well)")) note.requires = get_setting_info("enable_volumetric_lighting").requires diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 342fc24a6..2f7af3fae 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -616,34 +616,12 @@ exposure_compensation (Exposure compensation) float 0.0 -1.0 1.0 # Requires: shaders, enable_post_processing debanding (Enable Debanding) bool true -[**Bloom] - # Set to true to enable bloom effect. # Bright colors will bleed over the neighboring objects. # # Requires: shaders, enable_post_processing enable_bloom (Enable Bloom) bool false -# Defines how much bloom is applied to the rendered image -# Smaller values make bloom more subtle -# Range: from 0.01 to 1.0, default: 0.05 -# -# Requires: shaders, enable_post_processing, enable_bloom -bloom_intensity (Bloom Intensity) float 0.05 0.01 1.0 - -# Defines the magnitude of bloom overexposure. -# Range: from 0.1 to 10.0, default: 1.0 -# -# Requires: shaders, enable_post_processing, enable_bloom -bloom_strength_factor (Bloom Strength Factor) float 1.0 0.1 10.0 - -# Logical value that controls how far the bloom effect spreads -# from the bright objects. -# Range: from 0.1 to 8, default: 1 -# -# Requires: shaders, enable_post_processing, enable_bloom -bloom_radius (Bloom Radius) float 1 0.1 8 - # Set to true to enable volumetric lighting effect (a.k.a. "Godrays"). # # Requires: shaders, enable_post_processing, enable_bloom diff --git a/doc/lua_api.md b/doc/lua_api.md index 92c19545f..ed41d7a22 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -8616,23 +8616,43 @@ child will follow movement and rotation of that bone. * values < 0 cause an effect similar to inversion, but keeping original luma and being symmetrical in terms of saturation (eg. -1 and 1 is the same saturation and luma, but different hues) + * This value has no effect on clients who have shaders or post-processing disabled. * `shadows` is a table that controls ambient shadows + * This has no effect on clients who have the "Dynamic Shadows" effect disabled. * `intensity` sets the intensity of the shadows from 0 (no shadows, default) to 1 (blackness) - * This value has no effect on clients who have the "Dynamic Shadows" shader disabled. * `tint` tints the shadows with the provided color, with RGB values ranging from 0 to 255. (default `{r=0, g=0, b=0}`) - * This value has no effect on clients who have the "Dynamic Shadows" shader disabled. * `exposure` is a table that controls automatic exposure. The basic exposure factor equation is `e = 2^exposure_correction / clamp(luminance, 2^luminance_min, 2^luminance_max)` + * This has no effect on clients who have the "Automatic Exposure" effect disabled. * `luminance_min` set the lower luminance boundary to use in the calculation (default: `-3.0`) * `luminance_max` set the upper luminance boundary to use in the calculation (default: `-3.0`) * `exposure_correction` correct observed exposure by the given EV value (default: `0.0`) * `speed_dark_bright` set the speed of adapting to bright light (default: `1000.0`) * `speed_bright_dark` set the speed of adapting to dark scene (default: `1000.0`) * `center_weight_power` set the power factor for center-weighted luminance measurement (default: `1.0`) + * `bloom` is a table that controls bloom. + * This has no effect on clients with protocol version < 46 or clients who + have the "Bloom" effect disabled. + * `intensity` defines much bloom is applied to the rendered image. + * Recommended range: from 0.0 to 1.0, default: 0.05 + * If set to 0, bloom is disabled. + * The default value is to be changed from 0.05 to 0 in the future. + If you wish to keep the current default value, you should set it + explicitly. + * `strength_factor` defines the magnitude of bloom overexposure. + * Recommended range: from 0.1 to 10.0, default: 1.0 + * `radius` is a logical value that controls how far the bloom effect + spreads from the bright objects. + * Recommended range: from 0.1 to 8.0, default: 1.0 + * The behavior of values outside the recommended range is unspecified. * `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. + * This has no effect on clients who have the "Volumetric Lighting" or "Bloom" effects disabled. + * `strength`: sets the strength of the volumetric light effect from 0 (off, default) to 1 (strongest). + * `0.2` is a reasonable standard value. + * Currently, bloom `intensity` and `strength_factor` affect volumetric + lighting `strength` and vice versa. This behavior is to be changed + in the future, do not rely on it. * `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..20448d925 100644 --- a/games/devtest/mods/lighting/init.lua +++ b/games/devtest/mods/lighting/init.lua @@ -14,7 +14,21 @@ local lighting_sections = { {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}, } - } + }, + { + n = "bloom", d = "Bloom", + entries = { + {n = "intensity", d = "Intensity", min = 0, max = 1}, + {n = "strength_factor", d = "Strength Factor", min = 0.1, max = 10}, + {n = "radius", d = "Radius", min = 0.1, max = 8}, + }, + }, + { + n = "volumetric_light", d = "Volumetric Lighting", + entries = { + {n = "strength", d = "Strength", min = 0, max = 1}, + }, + }, } local function dump_lighting(lighting) @@ -59,38 +73,40 @@ minetest.register_chatcommand("set_lighting", { local lighting = player:get_lighting() local exposure = lighting.exposure or {} - local form = { - "formspec_version[2]", - "size[15,30]", - "position[0.99,0.15]", - "anchor[1,0]", - "padding[0.05,0.1]", - "no_prepend[]" - }; - + local content = {} 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.."]") + table.insert(content, "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]") + table.insert(content, "label[2,"..line..";"..v.d.."]") + table.insert(content, "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.."]") + table.insert(content, "scrollbar[2,"..(line+0.7)..";12,1;horizontal;"..section.n.."."..v.n..";"..sb_scale.."]") line = line + 2.7 end line = line + 1 end + local form = { + "formspec_version[2]", + "size[15,", line, "]", + "position[0.99,0.15]", + "anchor[1,0]", + "padding[0.05,0.1]", + "no_prepend[]", + } + table.insert_all(form, content) + 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}) diff --git a/src/client/game.cpp b/src/client/game.cpp index 9dd3a0e83..f1e798a52 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -405,11 +405,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter float m_user_exposure_compensation; bool m_bloom_enabled; CachedPixelShaderSetting m_bloom_intensity_pixel{"bloomIntensity"}; - float m_bloom_intensity; CachedPixelShaderSetting m_bloom_strength_pixel{"bloomStrength"}; - float m_bloom_strength; CachedPixelShaderSetting m_bloom_radius_pixel{"bloomRadius"}; - float m_bloom_radius; CachedPixelShaderSetting m_saturation_pixel{"saturation"}; bool m_volumetric_light_enabled; CachedPixelShaderSetting @@ -421,11 +418,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter CachedPixelShaderSetting m_volumetric_light_strength_pixel{"volumetricLightStrength"}; - static constexpr std::array SETTING_CALLBACKS = { + static constexpr std::array SETTING_CALLBACKS = { "exposure_compensation", - "bloom_intensity", - "bloom_strength_factor", - "bloom_radius" }; public: @@ -433,12 +427,6 @@ public: { if (name == "exposure_compensation") m_user_exposure_compensation = g_settings->getFloat("exposure_compensation", -1.0f, 1.0f); - if (name == "bloom_intensity") - m_bloom_intensity = g_settings->getFloat("bloom_intensity", 0.01f, 1.0f); - if (name == "bloom_strength_factor") - m_bloom_strength = RenderingEngine::BASE_BLOOM_STRENGTH * g_settings->getFloat("bloom_strength_factor", 0.1f, 10.0f); - if (name == "bloom_radius") - m_bloom_radius = g_settings->getFloat("bloom_radius", 0.1f, 8.0f); } static void settingsCallback(const std::string &name, void *userdata) @@ -457,9 +445,6 @@ public: m_user_exposure_compensation = g_settings->getFloat("exposure_compensation", -1.0f, 1.0f); m_bloom_enabled = g_settings->getBool("enable_bloom"); - m_bloom_intensity = g_settings->getFloat("bloom_intensity", 0.01f, 1.0f); - m_bloom_strength = RenderingEngine::BASE_BLOOM_STRENGTH * g_settings->getFloat("bloom_strength_factor", 0.1f, 10.0f); - m_bloom_radius = g_settings->getFloat("bloom_radius", 0.1f, 8.0f); m_volumetric_light_enabled = g_settings->getBool("enable_volumetric_lighting") && m_bloom_enabled; } @@ -511,7 +496,9 @@ 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 auto &lighting = m_client->getEnv().getLocalPlayer()->getLighting(); + + 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), @@ -524,12 +511,14 @@ public: m_exposure_params_pixel.set(exposure_buffer.data(), services); if (m_bloom_enabled) { - m_bloom_intensity_pixel.set(&m_bloom_intensity, services); - m_bloom_radius_pixel.set(&m_bloom_radius, services); - m_bloom_strength_pixel.set(&m_bloom_strength, services); + float intensity = std::max(lighting.bloom_intensity, 0.0f); + m_bloom_intensity_pixel.set(&intensity, services); + float strength_factor = std::max(lighting.bloom_strength_factor, 0.0f); + m_bloom_strength_pixel.set(&strength_factor, services); + float radius = std::max(lighting.bloom_radius, 0.0f); + m_bloom_radius_pixel.set(&radius, services); } - const auto &lighting = m_client->getEnv().getLocalPlayer()->getLighting(); float saturation = lighting.saturation; m_saturation_pixel.set(&saturation, services); diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp index c4933e062..b709fc7bf 100644 --- a/src/client/renderingengine.cpp +++ b/src/client/renderingengine.cpp @@ -41,7 +41,6 @@ with this program; if not, write to the Free Software Foundation, Inc., RenderingEngine *RenderingEngine::s_singleton = nullptr; const video::SColor RenderingEngine::MENU_SKY_COLOR = video::SColor(255, 140, 186, 250); -const float RenderingEngine::BASE_BLOOM_STRENGTH = 1.0f; /* Helper classes */ diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h index 7f7518f61..5f6890c8b 100644 --- a/src/client/renderingengine.h +++ b/src/client/renderingengine.h @@ -81,7 +81,6 @@ class RenderingEngine { public: static const video::SColor MENU_SKY_COLOR; - static const float BASE_BLOOM_STRENGTH; RenderingEngine(IEventReceiver *eventReceiver); ~RenderingEngine(); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 12946b06d..ae9180e72 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -332,9 +332,6 @@ void set_default_settings() settings->setDefault("antialiasing", "none"); settings->setDefault("enable_bloom", "false"); settings->setDefault("enable_bloom_debug", "false"); - settings->setDefault("bloom_strength_factor", "1.0"); - settings->setDefault("bloom_intensity", "0.05"); - settings->setDefault("bloom_radius", "1"); settings->setDefault("enable_volumetric_lighting", "false"); settings->setDefault("enable_water_reflections", "false"); settings->setDefault("enable_translucent_foliage", "false"); diff --git a/src/lighting.h b/src/lighting.h index fbf10b1c9..b0ba714b9 100644 --- a/src/lighting.h +++ b/src/lighting.h @@ -57,4 +57,7 @@ struct Lighting float saturation {1.0f}; float volumetric_light_strength {0.0f}; video::SColor shadow_tint {255, 0, 0, 0}; + float bloom_intensity {0.05f}; + float bloom_strength_factor {1.0f}; + float bloom_radius {1.0f}; }; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 2716879f4..725b6a5c7 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1819,4 +1819,9 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt) *pkt >> lighting.volumetric_light_strength; if (pkt->getRemainingBytes() >= 4) *pkt >> lighting.shadow_tint; + if (pkt->getRemainingBytes() >= 12) { + *pkt >> lighting.bloom_intensity + >> lighting.bloom_strength_factor + >> lighting.bloom_radius; + } } diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index a11308a2e..b9ea0a4e4 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -2649,6 +2649,14 @@ 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, "bloom"); + if (lua_istable(L, -1)) { + lighting.bloom_intensity = getfloatfield_default(L, -1, "intensity", lighting.bloom_intensity); + lighting.bloom_strength_factor = getfloatfield_default(L, -1, "strength_factor", lighting.bloom_strength_factor); + lighting.bloom_radius = getfloatfield_default(L, -1, "radius", lighting.bloom_radius); + } + lua_pop(L, 1); // bloom } getServer(L)->setLighting(player, lighting); @@ -2693,6 +2701,14 @@ 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); // "bloom" + lua_pushnumber(L, lighting.bloom_intensity); + lua_setfield(L, -2, "intensity"); + lua_pushnumber(L, lighting.bloom_strength_factor); + lua_setfield(L, -2, "strength_factor"); + lua_pushnumber(L, lighting.bloom_radius); + lua_setfield(L, -2, "radius"); + lua_setfield(L, -2, "bloom"); return 1; } diff --git a/src/server.cpp b/src/server.cpp index e4fecf7c1..037857b21 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1919,6 +1919,8 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting) << lighting.exposure.center_weight_power; pkt << lighting.volumetric_light_strength << lighting.shadow_tint; + pkt << lighting.bloom_intensity << lighting.bloom_strength_factor << + lighting.bloom_radius; Send(&pkt); }