From aea9242a968ad4cf92fe528ce42e40066b35e10b Mon Sep 17 00:00:00 2001 From: Gregor Parzefall <82708541+grorp@users.noreply.github.com> Date: Thu, 24 Aug 2023 20:16:36 +0200 Subject: [PATCH] Allow nodes to have their post_effect_color affected by lighting (#13637) Co-authored-by: DS --- doc/lua_api.md | 6 +++- games/devtest/mods/basenodes/init.lua | 4 +++ games/devtest/mods/testnodes/properties.lua | 33 ++++++++++++++++++ ...stnodes_post_effect_color_shaded_false.png | Bin 0 -> 107 bytes ...estnodes_post_effect_color_shaded_true.png | Bin 0 -> 105 bytes src/client/clientmap.cpp | 22 ++++++++---- src/client/clientmap.h | 3 +- src/client/game.cpp | 2 +- src/nodedef.cpp | 7 ++++ src/nodedef.h | 1 + src/script/common/c_content.cpp | 4 +++ 11 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 games/devtest/mods/testnodes/textures/testnodes_post_effect_color_shaded_false.png create mode 100644 games/devtest/mods/testnodes/textures/testnodes_post_effect_color_shaded_true.png diff --git a/doc/lua_api.md b/doc/lua_api.md index abff26a9d..be187bbd7 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -8785,7 +8785,11 @@ Used by `minetest.register_node`. -- Only when `paramtype2` supports palettes. post_effect_color = "#00000000", - -- Screen tint if player is inside node, see "ColorSpec" + -- Screen tint if a player is inside this node, see `ColorSpec`. + -- Color is alpha-blended over the screen. + + post_effect_color_shaded = false, + -- Determines whether `post_effect_color` is affected by lighting. paramtype = "none", -- See "Nodes" diff --git a/games/devtest/mods/basenodes/init.lua b/games/devtest/mods/basenodes/init.lua index aca117f25..249c7fbd8 100644 --- a/games/devtest/mods/basenodes/init.lua +++ b/games/devtest/mods/basenodes/init.lua @@ -147,6 +147,7 @@ minetest.register_node("basenodes:water_source", { liquid_alternative_source = "basenodes:water_source", liquid_viscosity = WATER_VISC, post_effect_color = {a = 64, r = 100, g = 100, b = 200}, + post_effect_color_shaded = true, groups = {water = 3, liquid = 3}, }) @@ -177,6 +178,7 @@ minetest.register_node("basenodes:water_flowing", { liquid_alternative_source = "basenodes:water_source", liquid_viscosity = WATER_VISC, post_effect_color = {a = 64, r = 100, g = 100, b = 200}, + post_effect_color_shaded = true, groups = {water = 3, liquid = 3}, }) @@ -206,6 +208,7 @@ minetest.register_node("basenodes:river_water_source", { liquid_renewable = false, liquid_range = 2, post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + post_effect_color_shaded = true, groups = {water = 3, liquid = 3, }, }) @@ -238,6 +241,7 @@ minetest.register_node("basenodes:river_water_flowing", { liquid_renewable = false, liquid_range = 2, post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + post_effect_color_shaded = true, groups = {water = 3, liquid = 3, }, }) diff --git a/games/devtest/mods/testnodes/properties.lua b/games/devtest/mods/testnodes/properties.lua index 6271f0add..e75cc8b69 100644 --- a/games/devtest/mods/testnodes/properties.lua +++ b/games/devtest/mods/testnodes/properties.lua @@ -588,3 +588,36 @@ minetest.register_node("testnodes:drowning_1", { groups = {dig_immediate=3}, }) +-- post_effect_color_shaded + +minetest.register_node("testnodes:post_effect_color_shaded_false", { + description = S("\"post_effect_color_shaded = false\" Node"), + + drawtype = "allfaces", + tiles = {"testnodes_post_effect_color_shaded_false.png"}, + use_texture_alpha = "blend", + paramtype = "light", + sunlight_propagates = true, + post_effect_color = {a = 128, r = 255, g = 255, b = 255}, + post_effect_color_shaded = false, + + walkable = false, + is_ground_content = false, + groups = {dig_immediate=3}, +}) + +minetest.register_node("testnodes:post_effect_color_shaded_true", { + description = S("\"post_effect_color_shaded = true\" Node"), + + drawtype = "allfaces", + tiles = {"testnodes_post_effect_color_shaded_true.png"}, + use_texture_alpha = "blend", + paramtype = "light", + sunlight_propagates = true, + post_effect_color = {a = 128, r = 255, g = 255, b = 255}, + post_effect_color_shaded = true, + + walkable = false, + is_ground_content = false, + groups = {dig_immediate=3}, +}) diff --git a/games/devtest/mods/testnodes/textures/testnodes_post_effect_color_shaded_false.png b/games/devtest/mods/testnodes/textures/testnodes_post_effect_color_shaded_false.png new file mode 100644 index 0000000000000000000000000000000000000000..a14713a070bafa7e45bd477f687514a20a3cf6aa GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6j67W&Lo|Yuf81}7H{#)A<@qo9 z&w0iPmBaNMCmVDa53fklSk-C9IJ18t!&H@H;?41l3_Ob26K>xNj0Eat@O1TaS?83{ F1OUQdADRFF literal 0 HcmV?d00001 diff --git a/games/devtest/mods/testnodes/textures/testnodes_post_effect_color_shaded_true.png b/games/devtest/mods/testnodes/textures/testnodes_post_effect_color_shaded_true.png new file mode 100644 index 0000000000000000000000000000000000000000..448cf91c8c2200d863ec795fcb9cb32f47c88897 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf63_M*NLn>}1|G3{EZ^XmL%Jbh* zz{$BKLBh$YML~t_*m{P`EF8WESVDN4)fQ-kFfcgm$`er8$C3`z%i!ti=d#Wzp$PyH C4;vW( literal 0 HcmV?d00001 diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index e77fd7116..838d74c03 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -125,7 +125,7 @@ ClientMap::~ClientMap() g_settings->deregisterChangedCallback("enable_raytraced_culling", on_settings_changed, this); } -void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset) +void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SColor light_color) { v3s16 previous_node = floatToInt(m_camera_position, BS) + m_camera_offset; v3s16 previous_block = getContainerPos(previous_node, MAP_BLOCKSIZE); @@ -134,6 +134,7 @@ void ClientMap::updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset) m_camera_direction = dir; m_camera_fov = fov; m_camera_offset = offset; + m_camera_light_color = light_color; v3s16 current_node = floatToInt(m_camera_position, BS) + m_camera_offset; v3s16 current_block = getContainerPos(current_node, MAP_BLOCKSIZE); @@ -1057,21 +1058,30 @@ void ClientMap::renderPostFx(CameraMode cam_mode) MapNode n = getNode(floatToInt(m_camera_position, BS)); const ContentFeatures& features = m_nodedef->get(n); - video::SColor post_effect_color = features.post_effect_color; + video::SColor post_color = features.post_effect_color; + + if (features.post_effect_color_shaded) { + auto apply_light = [] (u32 color, u32 light) { + return core::clamp(core::round32(color * light / 255.0f), 0, 255); + }; + post_color.setRed(apply_light(post_color.getRed(), m_camera_light_color.getRed())); + post_color.setGreen(apply_light(post_color.getGreen(), m_camera_light_color.getGreen())); + post_color.setBlue(apply_light(post_color.getBlue(), m_camera_light_color.getBlue())); + } // If the camera is in a solid node, make everything black. // (first person mode only) if (features.solidness == 2 && cam_mode == CAMERA_MODE_FIRST && - !m_control.allow_noclip) { - post_effect_color = video::SColor(255, 0, 0, 0); + !m_control.allow_noclip) { + post_color = video::SColor(255, 0, 0, 0); } - if (post_effect_color.getAlpha() != 0) { + if (post_color.getAlpha() != 0) { // Draw a full-screen rectangle video::IVideoDriver* driver = SceneManager->getVideoDriver(); v2u32 ss = driver->getScreenSize(); core::rect rect(0,0, ss.X, ss.Y); - driver->draw2DRectangle(post_effect_color, rect); + driver->draw2DRectangle(post_color, rect); } } diff --git a/src/client/clientmap.h b/src/client/clientmap.h index 4d565ec9f..13c320d9a 100644 --- a/src/client/clientmap.h +++ b/src/client/clientmap.h @@ -88,7 +88,7 @@ public: ISceneNode::drop(); // calls destructor } - void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset); + void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset, video::SColor light_color); /* Forcefully get a sector from somewhere @@ -201,6 +201,7 @@ private: v3f m_camera_direction = v3f(0,0,1); f32 m_camera_fov = M_PI; v3s16 m_camera_offset; + video::SColor m_camera_light_color = video::SColor(0xFFFFFFFF); bool m_needs_update_transparent_meshes = true; std::map m_drawlist; diff --git a/src/client/game.cpp b/src/client/game.cpp index 827e14678..280788603 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3177,7 +3177,7 @@ void Game::updateCamera(f32 dtime) v3f camera_direction = camera->getDirection(); client->getEnv().getClientMap().updateCamera(camera_position, - camera_direction, camera_fov, camera_offset); + camera_direction, camera_fov, camera_offset, player->light_color); if (m_camera_offset_changed) { client->updateCameraOffset(camera_offset); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index fef55e7df..bdaf0ebed 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -415,6 +415,7 @@ void ContentFeatures::reset() node_dig_prediction = "air"; move_resistance = 0; liquid_move_physics = false; + post_effect_color_shaded = false; } void ContentFeatures::setAlphaFromLegacy(u8 legacy_alpha) @@ -543,6 +544,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const writeU8(os, alpha); writeU8(os, move_resistance); writeU8(os, liquid_move_physics); + writeU8(os, post_effect_color_shaded); } void ContentFeatures::deSerialize(std::istream &is, u16 protocol_version) @@ -656,6 +658,11 @@ void ContentFeatures::deSerialize(std::istream &is, u16 protocol_version) if (is.eof()) throw SerializationError(""); liquid_move_physics = tmp; + + tmp = readU8(is); + if (is.eof()) + throw SerializationError(""); + post_effect_color_shaded = tmp; } catch(SerializationError &e) {}; } diff --git a/src/nodedef.h b/src/nodedef.h index 05ba10266..b1ec1e5ee 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -364,6 +364,7 @@ struct ContentFeatures std::vector connects_to_ids; // Post effect color, drawn when the camera is inside the node. video::SColor post_effect_color; + bool post_effect_color_shaded; // Flowing liquid or leveled nodebox, value = default level u8 leveled; // Maximum value for leveled nodes diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 4da9a6a4e..94f8dcabe 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -728,6 +728,8 @@ void read_content_features(lua_State *L, ContentFeatures &f, int index) read_color(L, -1, &f.post_effect_color); lua_pop(L, 1); + getboolfield(L, index, "post_effect_color_shaded", f.post_effect_color_shaded); + f.param_type = (ContentParamType)getenumfield(L, index, "paramtype", ScriptApiNode::es_ContentParamType, CPT_NONE); f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2", @@ -959,6 +961,8 @@ void push_content_features(lua_State *L, const ContentFeatures &c) push_ARGB8(L, c.post_effect_color); lua_setfield(L, -2, "post_effect_color"); + lua_pushboolean(L, c.post_effect_color_shaded); + lua_setfield(L, -2, "post_effect_color_shaded"); lua_pushnumber(L, c.leveled); lua_setfield(L, -2, "leveled"); lua_pushnumber(L, c.leveled_max);