From 698a63cc5ccddf5b8f3c84b5a52d958915647e14 Mon Sep 17 00:00:00 2001 From: Andrey2470T Date: Wed, 1 May 2024 01:00:30 +0300 Subject: [PATCH] Fixed the particles light calculation --- .../shaders/nodes_shader/opengl_fragment.glsl | 2 - .../object_shader/opengl_fragment.glsl | 2 - src/client/CMakeLists.txt | 1 + src/client/clientenvironment.cpp | 1 + src/client/content_cao.cpp | 1 + src/client/content_mapblock.cpp | 1 + src/client/game.cpp | 1 + src/client/light_colors.cpp | 98 +++++++++++++++++++ src/client/light_colors.h | 61 ++++++++++++ src/client/mapblock_mesh.cpp | 78 +-------------- src/client/mapblock_mesh.h | 41 -------- src/client/particles.cpp | 3 +- 12 files changed, 167 insertions(+), 123 deletions(-) create mode 100644 src/client/light_colors.cpp create mode 100644 src/client/light_colors.h diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index 086856237..46977b147 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -8,7 +8,6 @@ uniform float fogShadingParameter; // The cameraOffset is the current center of the visible world. uniform highp vec3 cameraOffset; uniform float animationTimer; - #ifdef ENABLE_DYNAMIC_SHADOWS // shadow texture uniform sampler2D ShadowMapSampler; @@ -376,7 +375,6 @@ void main(void) #endif color = base.rgb; - vec4 col = vec4(color.rgb * varColor.rgb, 1.0); #ifdef ENABLE_DYNAMIC_SHADOWS diff --git a/client/shaders/object_shader/opengl_fragment.glsl b/client/shaders/object_shader/opengl_fragment.glsl index e2f3bc2cb..2b8af3fa9 100644 --- a/client/shaders/object_shader/opengl_fragment.glsl +++ b/client/shaders/object_shader/opengl_fragment.glsl @@ -8,7 +8,6 @@ uniform float fogShadingParameter; // The cameraOffset is the current center of the visible world. uniform highp vec3 cameraOffset; uniform float animationTimer; - #ifdef ENABLE_DYNAMIC_SHADOWS // shadow texture uniform sampler2D ShadowMapSampler; @@ -379,7 +378,6 @@ void main(void) #endif color = base.rgb; - vec4 col = vec4(color.rgb * varColor.rgb, 1.0); col.rgb *= vIDiff; diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index d451d0911..cf211ce48 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -57,6 +57,7 @@ set(client_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp ${CMAKE_CURRENT_SOURCE_DIR}/keycode.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/light_colors.cpp ${CMAKE_CURRENT_SOURCE_DIR}/localplayer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mapblock_mesh.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mesh.cpp diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index 7e9fb26d2..35bb19a69 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include #include "client/renderingengine.h" +#include "light_colors.h" /* ClientEnvironment diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 0044cc16e..6512c4a06 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -48,6 +48,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/shader.h" #include "client/minimap.h" #include +#include "light_colors.h" class Settings; struct ToolCapabilities; diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp index c351c4b80..9132f0410 100644 --- a/src/client/content_mapblock.cpp +++ b/src/client/content_mapblock.cpp @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "client/renderingengine.h" #include "client.h" #include "noise.h" +#include "light_colors.h" // Distance of light extrapolation (for oversized nodes) // After this distance, it gives up and considers light level constant diff --git a/src/client/game.cpp b/src/client/game.cpp index 669950b81..4f648b56f 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -79,6 +79,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "clientdynamicinfo.h" #include +#include "light_colors.h" #if USE_SOUND #include "client/sound/sound_openal.h" diff --git a/src/client/light_colors.cpp b/src/client/light_colors.cpp new file mode 100644 index 000000000..1b507ea09 --- /dev/null +++ b/src/client/light_colors.cpp @@ -0,0 +1,98 @@ +/* +Minetest +Copyright (C) 2024 Andrey2470T, AndreyT + +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. +*/ + +#include "light_colors.h" + +video::SColor encode_light(u16 light, u8 emissive_light) +{ + // Get components + u32 day = (light & 0xff); + u32 night = (light >> 8); + // Add emissive light + night += emissive_light * 2.5f; + if (night > 255) + night = 255; + // Since we don't know if the day light is sunlight or + // artificial light, assume it is artificial when the night + // light bank is also lit. + if (day < night) + day = 0; + else + day = day - night; + u32 sum = day + night; + // Ratio of sunlight: + u32 r; + if (sum > 0) + r = day * 255 / sum; + else + r = 0; + // Average light: + float b = (day + night) / 2; + return video::SColor(r, b, b, b); +} + +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 final_color_blend(video::SColor *result, + u16 light, u32 daynight_ratio, video::SColor ambientLight) +{ + video::SColorf dayLight; + get_sunlight_color(&dayLight, daynight_ratio); + final_color_blend(result, + encode_light(light, 0), dayLight, ambientLight); +} + +void final_color_blend(video::SColor *result, + const video::SColor &data, const video::SColorf &dayLight, + video::SColor ambientLight) +{ + static const video::SColorf artificialColor(1.04f, 1.04f, 1.04f); + + video::SColorf c(data); + f32 n = 1 - c.a; + + f32 r = c.r * (c.a * dayLight.r + n * artificialColor.r) * 2.0f; + f32 g = c.g * (c.a * dayLight.g + n * artificialColor.g) * 2.0f; + f32 b = c.b * (c.a * dayLight.b + n * artificialColor.b) * 2.0f; + + // Emphase blue a bit in darker places + // Each entry of this array represents a range of 8 blue levels + static const u8 emphase_blue_when_dark[32] = { + 1, 4, 6, 6, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + b += emphase_blue_when_dark[irr::core::clamp((s32) ((r + g + b) / 3 * 255), + 0, 255) / 8] / 255.0f; + + // Add ambient light + r += ambientLight.getRed() / 255.f; + g += ambientLight.getGreen() / 255.f; + b += ambientLight.getBlue() / 255.f; + + result->setRed(core::clamp((s32)(r * 255.f), 0, 255)); + result->setGreen(core::clamp((s32)(g * 255.f), 0, 255)); + result->setBlue(core::clamp((s32)(b * 255.f), 0, 255)); +} diff --git a/src/client/light_colors.h b/src/client/light_colors.h new file mode 100644 index 000000000..91fd0e9aa --- /dev/null +++ b/src/client/light_colors.h @@ -0,0 +1,61 @@ +/* +Minetest +Copyright (C) 2024 Andrey2470T, AndreyT + +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. +*/ + +#include "irrlichttypes_extrabloated.h" + +/*! + * Encodes light of a node. + * The result is not the final color, but a + * half-baked vertex color. + * You have to multiply the resulting color + * with the node's color. + * + * \param light the first 8 bits are day light, + * the last 8 bits are night light + * \param emissive_light amount of light the surface emits, + * from 0 to LIGHT_SUN. + */ +video::SColor encode_light(u16 light, u8 emissive_light); + +/*! + * Returns the sunlight's color from the current + * day-night ratio. + */ +void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio); + +/*! + * Gives the final SColor shown on screen. + * + * \param result output color + * \param light first 8 bits are day light, second 8 bits are + * night light + */ +void final_color_blend(video::SColor *result, + u16 light, u32 daynight_ratio, video::SColor ambientLight=video::SColor(255,0,0,0)); + +/*! + * Gives the final SColor shown on screen. + * + * \param result output color + * \param data the half-baked vertex color + * \param dayLight color of the sunlight + */ +void final_color_blend(video::SColor *result, + const video::SColor &data, const video::SColorf &dayLight, + video::SColor ambientLight=video::SColor(255,0,0,0)); diff --git a/src/client/mapblock_mesh.cpp b/src/client/mapblock_mesh.cpp index 4121379d2..903148beb 100644 --- a/src/client/mapblock_mesh.cpp +++ b/src/client/mapblock_mesh.cpp @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include "client/texturesource.h" +#include "light_colors.h" /* MeshMakeData @@ -281,55 +282,6 @@ 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 final_color_blend(video::SColor *result, - u16 light, u32 daynight_ratio, video::SColor ambientLight) -{ - video::SColorf dayLight; - get_sunlight_color(&dayLight, daynight_ratio); - final_color_blend(result, - encode_light(light, 0), dayLight, ambientLight); -} - -void final_color_blend(video::SColor *result, - const video::SColor &data, const video::SColorf &dayLight, - video::SColor ambientLight) -{ - static const video::SColorf artificialColor(1.04f, 1.04f, 1.04f); - - video::SColorf c(data); - f32 n = 1 - c.a; - - f32 r = c.r * (c.a * dayLight.r + n * artificialColor.r) * 2.0f; - f32 g = c.g * (c.a * dayLight.g + n * artificialColor.g) * 2.0f; - f32 b = c.b * (c.a * dayLight.b + n * artificialColor.b) * 2.0f; - - // Emphase blue a bit in darker places - // Each entry of this array represents a range of 8 blue levels - static const u8 emphase_blue_when_dark[32] = { - 1, 4, 6, 6, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - - b += emphase_blue_when_dark[irr::core::clamp((s32) ((r + g + b) / 3 * 255), - 0, 255) / 8] / 255.0f; - - // Add ambient light - r += ambientLight.getRed() / 255.f; - g += ambientLight.getGreen() / 255.f; - b += ambientLight.getBlue() / 255.f; - - result->setRed(core::clamp((s32)(r * 255.f), 0, 255)); - result->setGreen(core::clamp((s32)(g * 255.f), 0, 255)); - result->setBlue(core::clamp((s32)(b * 255.f), 0, 255)); -} /* Mesh generation helpers @@ -955,34 +907,6 @@ void MapBlockMesh::consolidateTransparentBuffers() } } -video::SColor encode_light(u16 light, u8 emissive_light) -{ - // Get components - u32 day = (light & 0xff); - u32 night = (light >> 8); - // Add emissive light - night += emissive_light * 2.5f; - if (night > 255) - night = 255; - // Since we don't know if the day light is sunlight or - // artificial light, assume it is artificial when the night - // light bank is also lit. - if (day < night) - day = 0; - else - day = day - night; - u32 sum = day + night; - // Ratio of sunlight: - u32 r; - if (sum > 0) - r = day * 255 / sum; - else - r = 0; - // Average light: - float b = (day + night) / 2; - return video::SColor(r, b, b, b); -} - u8 get_solid_sides(MeshMakeData *data) { std::unordered_map results; diff --git a/src/client/mapblock_mesh.h b/src/client/mapblock_mesh.h index 442f0a577..98a5c6ca6 100644 --- a/src/client/mapblock_mesh.h +++ b/src/client/mapblock_mesh.h @@ -284,53 +284,12 @@ class MapBlockMesh std::vector m_transparent_buffers; }; -/*! - * Encodes light of a node. - * The result is not the final color, but a - * half-baked vertex color. - * You have to multiply the resulting color - * with the node's color. - * - * \param light the first 8 bits are day light, - * the last 8 bits are night light - * \param emissive_light amount of light the surface emits, - * from 0 to LIGHT_SUN. - */ -video::SColor encode_light(u16 light, u8 emissive_light); - // Compute light at node u16 getInteriorLight(MapNode n, s32 increment, const NodeDefManager *ndef); u16 getFaceLight(MapNode n, MapNode n2, const NodeDefManager *ndef); u16 getSmoothLightSolid(const v3s16 &p, const v3s16 &face_dir, const v3s16 &corner, MeshMakeData *data); u16 getSmoothLightTransparent(const v3s16 &p, const v3s16 &corner, MeshMakeData *data); -/*! - * Returns the sunlight's color from the current - * day-night ratio. - */ -void get_sunlight_color(video::SColorf *sunlight, u32 daynight_ratio); - -/*! - * Gives the final SColor shown on screen. - * - * \param result output color - * \param light first 8 bits are day light, second 8 bits are - * night light - */ -void final_color_blend(video::SColor *result, - u16 light, u32 daynight_ratio, video::SColor ambientLight=video::SColor(255,0,0,0)); - -/*! - * Gives the final SColor shown on screen. - * - * \param result output color - * \param data the half-baked vertex color - * \param dayLight color of the sunlight - */ -void final_color_blend(video::SColor *result, - const video::SColor &data, const video::SColorf &dayLight, - video::SColor ambientLight=video::SColor(255,0,0,0)); - // Retrieves the TileSpec of a face of a node // Adds MATERIAL_FLAG_CRACK if the node is cracked // TileSpec should be passed as reference due to the underlying TileFrame and its vector diff --git a/src/client/particles.cpp b/src/client/particles.cpp index 86592c776..aeffd600b 100644 --- a/src/client/particles.cpp +++ b/src/client/particles.cpp @@ -36,6 +36,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "profiler.h" #include "client/mapblock_mesh.h" +#include "light_colors.h" ClientParticleTexture::ClientParticleTexture(const ServerParticleTexture& p, ITextureSource *tsrc) { @@ -186,7 +187,7 @@ video::SColor Particle::updateLight(ClientEnvironment *env) else light = blend_light(env->getDayNightRatio(), LIGHT_SUN, 0); - light += m_p.glow; + light = decode_light(light + m_p.glow); video::SColor light_color{0xFFFFFFFF};