diff --git a/client/shaders/nodes_shader/opengl_fragment.glsl b/client/shaders/nodes_shader/opengl_fragment.glsl index f0159c67c..1b9cf6df2 100644 --- a/client/shaders/nodes_shader/opengl_fragment.glsl +++ b/client/shaders/nodes_shader/opengl_fragment.glsl @@ -539,7 +539,7 @@ void main(void) #endif #if (defined(ENABLE_NODE_SPECULAR) && !MATERIAL_WATER_REFLECTIONS) - // Apply specular to blocks. + // Apply specular to nodes. if (dot(v_LightDirection, vNormal) < 0.0) { // This intensity/roughness is a placeholder and should be replaced by proper specular maps. float intensity = 0.35 * min(1.0, length(varColor.rgb * base.rgb)); diff --git a/client/shaders/nodes_shader/opengl_vertex.glsl b/client/shaders/nodes_shader/opengl_vertex.glsl index e5d480f6c..34fe2c5c7 100644 --- a/client/shaders/nodes_shader/opengl_vertex.glsl +++ b/client/shaders/nodes_shader/opengl_vertex.glsl @@ -57,7 +57,7 @@ uniform float xyPerspectiveBias1; uniform float zPerspectiveBias; #ifdef ENABLE_TINTED_SUNLIGHT - uniform vec3 beta_r0_l; + uniform vec3 scattering_coefficients; #endif #ifdef ENABLE_DYNAMIC_SHADOWS @@ -155,11 +155,11 @@ float snoise(vec3 p) vec3 getDirectLightScatteringAtGround(vec3 v_LightDirection) { // Based on talk at 2002 Game Developers Conference by Naty Hoffman and Arcot J. Preetham - const float beta_r0 = 1e-5; // Rayleigh scattering beta + const float unit_conversion = 1e-5; // Rayleigh scattering beta const float atmosphere_height = 15000.; // height of the atmosphere in meters // sun/moon light at the ground level, after going through the atmosphere - return exp(-beta_r0_l * beta_r0 * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); + return exp(-scattering_coefficients * unit_conversion * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); } #endif @@ -221,7 +221,7 @@ void main(void) // The alpha gives the ratio of sunlight in the incoming light. nightRatio = 1.0 - color.a; color.rgb = color.rgb * (color.a * dayLight.rgb + - nightRatio * 2.0 * artificialLight.rgb) * 2.0; + nightRatio * max(artificialLight.rgb, vec3(0.0))) * 2.0; color.a = 1.0; // Emphase blue a bit in darker places diff --git a/client/shaders/object_shader/opengl_vertex.glsl b/client/shaders/object_shader/opengl_vertex.glsl index 8ed1c6f67..f6fe0e4e6 100644 --- a/client/shaders/object_shader/opengl_vertex.glsl +++ b/client/shaders/object_shader/opengl_vertex.glsl @@ -42,6 +42,10 @@ uniform float xyPerspectiveBias0; uniform float xyPerspectiveBias1; uniform float zPerspectiveBias; +#ifdef ENABLE_TINTED_SUNLIGHT + uniform vec3 scattering_coefficients; +#endif + #ifdef ENABLE_DYNAMIC_SHADOWS vec4 getRelativePosition(in vec4 position) @@ -90,19 +94,17 @@ float directional_ambient(vec3 normal) return dot(v, vec3(0.670820, 1.000000, 0.836660)); } -vec3 getDirectLightScatteringAtGround(vec3 v_LightDirection) -{ - // Based on talk at 2002 Game Developers Conference by Naty Hoffman and Arcot J. Preetham - const float beta_r0 = 1e-5; // Rayleigh scattering beta +#ifdef ENABLE_TINTED_SUNLIGHT + vec3 getDirectLightScatteringAtGround(vec3 v_LightDirection) + { + // Based on talk at 2002 Game Developers Conference by Naty Hoffman and Arcot J. Preetham + const float unit_conversion = 1e-5; // Rayleigh scattering beta - // These factors are calculated based on expected value of scattering factor of 1e-5 - // for Nitrogen at 532nm (green), 2e25 molecules/m3 in atmosphere - const vec3 beta_r0_l = vec3(3.3362176e-01, 8.75378289198826e-01, 1.95342379700656) * beta_r0; // wavelength-dependent scattering - - const float atmosphere_height = 15000.; // height of the atmosphere in meters - // sun/moon light at the ground level, after going through the atmosphere - return exp(-beta_r0_l * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); -} + const float atmosphere_height = 15000.; // height of the atmosphere in meters + // sun/moon light at the ground level, after going through the atmosphere + return exp(-scattering_coefficients * unit_conversion * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); + } +#endif void main(void) { @@ -131,7 +133,7 @@ void main(void) // The alpha gives the ratio of sunlight in the incoming light. nightRatio = 1.0 - color.a; color.rgb = color.rgb * (color.a * dayLight.rgb + - nightRatio * 2.0 * artificialLight.rgb) * 2.0; + nightRatio * max(artificialLight.rgb, vec3(0.0))) * 2.0; color.a = 1.0; // Emphase blue a bit in darker places @@ -174,6 +176,7 @@ void main(void) perspective_factor = pFactor; // The sun rises at 5:00 and sets at 19:00, which corresponds to 5/24=0.208 and 19/24 = 0.792. + float nightFactor = 0.; sunTint = vec3(1.0); if (f_timeofday < 0.208) { adj_shadow_strength = f_shadow_strength * 0.5 * @@ -185,6 +188,7 @@ void main(void) adj_shadow_strength = f_shadow_strength * mtsmoothstep(0.208, 0.238, f_timeofday) * (1.0 - mtsmoothstep(0.762, 0.792, f_timeofday)); + nightFactor = adj_shadow_strength / f_shadow_strength; #ifdef ENABLE_TINTED_SUNLIGHT float tint_strength = 1.0 - mtsmoothstep(0.792, 0.5, f_timeofday) * mtsmoothstep(0.208, 0.5, f_timeofday); sunTint = mix(vec3(1.0), getDirectLightScatteringAtGround(v_LightDirection), nightFactor * tint_strength); diff --git a/client/shaders/volumetric_light/opengl_fragment.glsl b/client/shaders/volumetric_light/opengl_fragment.glsl index 0a2bba60e..cc7045d22 100644 --- a/client/shaders/volumetric_light/opengl_fragment.glsl +++ b/client/shaders/volumetric_light/opengl_fragment.glsl @@ -24,7 +24,7 @@ varying mediump vec2 varTexCoord; centroid varying vec2 varTexCoord; #endif -uniform vec3 beta_r0_l; +uniform vec3 scattering_coefficients; const float far = 1000.; float mapDepth(float depth) @@ -63,12 +63,11 @@ float sampleVolumetricLight(vec2 uv, vec3 lightVec, float rawDepth) vec3 getDirectLightScatteringAtGround(vec3 v_LightDirection) { // Based on talk at 2002 Game Developers Conference by Naty Hoffman and Arcot J. Preetham - const float beta_r0 = 1e-5; // Rayleigh scattering beta + const float unit_conversion = 1e-5; // Rayleigh scattering beta const float atmosphere_height = 15000.; // height of the atmosphere in meters // sun/moon light at the ground level, after going through the atmosphere - - return exp(-beta_r0_l * beta_r0 * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); + return exp(-scattering_coefficients * unit_conversion * atmosphere_height / (1e-5 - dot(v_LightDirection, vec3(0., 1., 0.)))); } vec3 applyVolumetricLight(vec3 color, vec2 uv, float rawDepth) diff --git a/doc/lua_api.md b/doc/lua_api.md index cd138c2d9..a814dd996 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -9029,7 +9029,7 @@ child will follow movement and rotation of that bone. * 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. - * `beta_r0`: the scattering coefficient that controls the tint of sunlight during sunrise and sunset. + * `scattering_coefficients`: the scattering coefficients that control the tint of sunlight during sunrise and sunset. * Defaults to { x = 3.3362176e-01, y = 8.75378289198826e-01, z = 1.95342379700656} which is physically accurate. * This may be used to create effects like differently colored sunsets on alien planets. * Setting all components to zero effectively disables tinted sunlight. @@ -9044,6 +9044,9 @@ child will follow movement and rotation of that bone. * `slope`: "Tints" the scene, affects brighter colors more (default: `{x=1.2, y=1.0, z=0.8}`) * `offset`: This can be used to brighten or darken the scene (default: `{x=0.0, y=0.0, z=0.0}`) * `power`: Tints mostly the darker parts of the scene (default: `{x=1.25, y=1.0, z=0.9}`) + * `artificial_light`: is a table that controls the color of artificial light (torches etc.). + * Values should be positive and vaguely around `1.0`, but can be higher or lower. + * Default: `{r=1.04, g=1.04, b=1.04}` * `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/src/client/game.cpp b/src/client/game.cpp index f0d89548b..6babe0dcb 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -217,7 +217,6 @@ class GameGlobalShaderUniformSetter : public IShaderUniformSetter }}; float m_user_exposure_compensation; bool m_bloom_enabled; - bool m_color_grading_enabled; CachedPixelShaderSetting m_bloom_intensity_pixel{"bloomIntensity"}; CachedPixelShaderSetting m_bloom_strength_pixel{"bloomStrength"}; CachedPixelShaderSetting m_bloom_radius_pixel{"bloomRadius"}; @@ -234,9 +233,9 @@ class GameGlobalShaderUniformSetter : public IShaderUniformSetter CachedPixelShaderSetting m_volumetric_light_strength_pixel{"volumetricLightStrength"}; CachedPixelShaderSetting - m_volumetric_beta_r0_pixel{ "beta_r0_l" }; + m_atmospheric_scattering_coefficients_pixel{ "scattering_coefficients" }; CachedVertexShaderSetting - m_volumetric_beta_r0_vertex{ "beta_r0_l" }; + m_atmospheric_scattering_coefficients_vertex{ "scattering_coefficients" }; CachedPixelShaderSetting m_cdl_slope_pixel{"cdl_slope"}; CachedPixelShaderSetting m_cdl_offset_pixel{"cdl_offset"}; CachedPixelShaderSetting m_cdl_power_pixel{"cdl_power"}; @@ -275,7 +274,6 @@ public: m_bloom_enabled = g_settings->getBool("enable_bloom"); m_volumetric_light_enabled = g_settings->getBool("enable_volumetric_lighting") && m_bloom_enabled; m_gamma = g_settings->getFloat("secondstage_gamma"); - m_color_grading_enabled = g_settings->getBool("enable_color_grading"); } ~GameGlobalShaderUniformSetter() @@ -356,12 +354,10 @@ public: m_foliage_translucency_pixel.set(&lighting.foliage_translucency, services); m_specular_intensity_pixel.set(&lighting.specular_intensity, services); - if (m_color_grading_enabled) { - const ColorDecisionList& cdl_params = lighting.cdl; - m_cdl_slope_pixel.set(cdl_params.slope, services); - m_cdl_offset_pixel.set(cdl_params.offset, services); - m_cdl_power_pixel.set(cdl_params.power, services); - } + const ColorDecisionList& cdl_params = lighting.cdl; + m_cdl_slope_pixel.set(cdl_params.slope, services); + m_cdl_offset_pixel.set(cdl_params.offset, services); + m_cdl_power_pixel.set(cdl_params.power, services); if (m_volumetric_light_enabled) { // Map directional light to screen space @@ -407,9 +403,9 @@ public: m_volumetric_light_strength_pixel.set(&volumetric_light_strength, services); } - v3f beta_r0 = lighting.volumetric_beta_r0; - m_volumetric_beta_r0_vertex.set(beta_r0, services); - m_volumetric_beta_r0_pixel.set(beta_r0, services); + v3f scattering_coefficients = lighting.scattering_coefficients; + m_atmospheric_scattering_coefficients_vertex.set(scattering_coefficients, services); + m_atmospheric_scattering_coefficients_pixel.set(scattering_coefficients, services); } void onSetMaterial(const video::SMaterial &material) override @@ -504,8 +500,9 @@ public: #undef PROVIDE bool enable_waving_water = g_settings->getBool("enable_waving_water"); + bool enable_water_reflections = g_settings->getBool("enable_water_reflections"); constants["ENABLE_WAVING_WATER"] = enable_waving_water ? 1 : 0; - if (enable_waving_water) { + if (enable_waving_water || enable_water_reflections) { constants["WATER_WAVE_HEIGHT"] = g_settings->getFloat("water_wave_height"); constants["WATER_WAVE_LENGTH"] = g_settings->getFloat("water_wave_length"); constants["WATER_WAVE_SPEED"] = g_settings->getFloat("water_wave_speed"); diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 16dac3d87..3116ed236 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -225,6 +225,9 @@ public: float shadow_soft_radius = std::max(1.f, g_settings->getFloat("shadow_soft_radius")); constants["SOFTSHADOWRADIUS"] = shadow_soft_radius; + + if (g_settings->getBool("enable_sun_tint")) + constants["ENABLE_TINTED_SUNLIGHT"] = 1; } if (g_settings->getBool("enable_bloom")) { diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index f61f4c4c6..143d1eafe 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -333,7 +333,6 @@ void set_default_settings() settings->setDefault("enable_waving_plants", "false"); settings->setDefault("exposure_compensation", "0.0"); settings->setDefault("enable_auto_exposure", "false"); - settings->setDefault("enable_color_grading", "false"); settings->setDefault("secondstage_gamma", "1.6"); settings->setDefault("debanding", "true"); settings->setDefault("antialiasing", "none"); @@ -343,7 +342,6 @@ void set_default_settings() settings->setDefault("enable_volumetric_depth_attenuation", "false"); settings->setDefault("enable_water_reflections", "false"); settings->setDefault("enable_translucent_foliage", "false"); - settings->setDefault("enable_node_specular", "false"); settings->setDefault("enable_tinted_fog", "false"); // Effects Shadows diff --git a/src/lighting.h b/src/lighting.h index 864262aa3..8ec935b26 100644 --- a/src/lighting.h +++ b/src/lighting.h @@ -80,8 +80,8 @@ struct Lighting float specular_intensity{0.0f}; // These factors are calculated based on expected value of scattering factor of 1e-5 // for Nitrogen at 532nm (green), 2e25 molecules/m3 in atmosphere - v3f volumetric_beta_r0{ 3.3362176e-01f, 8.753783e-01f, 1.9534237f }; - video::SColor artificial_light_color{ 255, 133, 133, 133 }; + v3f scattering_coefficients{ 3.3362176e-01f, 8.753783e-01f, 1.9534237f }; + video::SColorf artificial_light_color{ 1.0f, 1.04f, 1.04f, 1.04f }; video::SColor shadow_tint {255, 0, 0, 0}; float bloom_intensity {0.05f}; float bloom_strength_factor {1.0f}; diff --git a/src/log.h b/src/log.h index 0e34b2c83..599c253e4 100644 --- a/src/log.h +++ b/src/log.h @@ -62,7 +62,7 @@ private: // These calls explicitly use the templated version of operator<<, // so that they won't use the overloads created by ADD_NULL_CHECK. if (arg == nullptr) - return this->operator<< ("(null)"); + return this->operator<< ((const char*) ("(null)")); else return this->operator<< (std::forward(arg)); } diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 18e35e3f2..2d7421190 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1795,8 +1795,10 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt) >> lighting.bloom_radius; } if (pkt->getRemainingBytes() >= 72) { - *pkt >> lighting.artificial_light_color; - *pkt >> lighting.volumetric_beta_r0; + *pkt >> lighting.artificial_light_color.r + >> lighting.artificial_light_color.g + >> lighting.artificial_light_color.b; + *pkt >> lighting.scattering_coefficients; *pkt >> lighting.vignette.dark >> lighting.vignette.bright >> lighting.vignette.power; diff --git a/src/network/networkprotocol.cpp b/src/network/networkprotocol.cpp index 9bf2fa7eb..020b939f3 100644 --- a/src/network/networkprotocol.cpp +++ b/src/network/networkprotocol.cpp @@ -61,10 +61,10 @@ [scheduled bump for 5.10.0] PROTOCOL VERSION 47 Add particle blend mode "clip" - Add artificial light color, beta_r0, vignette, specular intensity, foliage translucency and cdl parameters to Lighting packets [scheduled bump for 5.11.0] PROTOCOL VERSION 48 - Add compression to some existing packets + Add compression to some existing packets, artificial light color, scattering_coefficients, + vignette, specular intensity, foliage translucency and cdl parameters to Lighting packets [scheduled bump for 5.12.0] */ diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 1ee00ae39..21cea5436 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -2660,8 +2660,10 @@ int ObjectRef::l_set_lighting(lua_State *L) lighting = player->getLighting(); lua_getfield(L, 2, "artificial_light"); - if (!lua_isnil(L, -1)) { - read_color(L, -1, &lighting.artificial_light_color); + if (lua_istable(L, -1)) { + getfloatfield(L, -1, "r", lighting.artificial_light_color.r); + getfloatfield(L, -1, "g", lighting.artificial_light_color.g); + getfloatfield(L, -1, "b", lighting.artificial_light_color.b); } lua_pop(L, 1); // artificial_light @@ -2694,11 +2696,11 @@ int ObjectRef::l_set_lighting(lua_State *L) getfloatfield(L, -1, "strength", lighting.volumetric_light_strength); lighting.volumetric_light_strength = rangelim(lighting.volumetric_light_strength, 0.0f, 1.0f); - lua_getfield(L, -1, "beta_r0"); + lua_getfield(L, -1, "scattering_coefficients"); if (!lua_isnil(L, -1)) { - lighting.volumetric_beta_r0 = read_v3f(L, -1); + lighting.scattering_coefficients = read_v3f(L, -1); } - lua_pop(L, 1); // beta_r0 + lua_pop(L, 1); // scattering_coefficients } lua_pop(L, 1); // volumetric_light @@ -2752,7 +2754,13 @@ int ObjectRef::l_get_lighting(lua_State *L) const Lighting &lighting = player->getLighting(); lua_newtable(L); // result - push_ARGB8(L, lighting.artificial_light_color); + lua_newtable(L); // artificial_light + lua_pushnumber(L, lighting.artificial_light_color.r); + lua_setfield(L, -2, "r"); + lua_pushnumber(L, lighting.artificial_light_color.g); + lua_setfield(L, -2, "g"); + lua_pushnumber(L, lighting.artificial_light_color.b); + lua_setfield(L, -2, "b"); lua_setfield(L, -2, "artificial_light"); lua_pushnumber(L, lighting.foliage_translucency); lua_setfield(L, -2, "foliage_translucency"); @@ -2783,8 +2791,8 @@ int ObjectRef::l_get_lighting(lua_State *L) lua_newtable(L); // "volumetric_light" lua_pushnumber(L, lighting.volumetric_light_strength); lua_setfield(L, -2, "strength"); - push_v3f(L, lighting.volumetric_beta_r0); - lua_setfield(L, -2, "beta_r0"); + push_v3f(L, lighting.scattering_coefficients); + lua_setfield(L, -2, "scattering_coefficients"); lua_setfield(L, -2, "volumetric_light"); lua_newtable(L); // "bloom" lua_pushnumber(L, lighting.bloom_intensity); diff --git a/src/server.cpp b/src/server.cpp index 6c0600b6b..c8ad9660a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1947,8 +1947,10 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting) pkt << lighting.volumetric_light_strength << lighting.shadow_tint; pkt << lighting.bloom_intensity << lighting.bloom_strength_factor << lighting.bloom_radius; - pkt << lighting.artificial_light_color; - pkt << lighting.volumetric_beta_r0; + pkt << lighting.artificial_light_color.r + << lighting.artificial_light_color.g + << lighting.artificial_light_color.b; + pkt << lighting.scattering_coefficients; pkt << lighting.vignette.dark << lighting.vignette.bright << lighting.vignette.power;