From e0374626152ebd8604aa110e54c6add2a68313a4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 12 Feb 2026 20:27:29 +0300 Subject: [PATCH] add 'sky_tint', 'clouds_tint', 'min_sky_light' weather parameters --- res/presets/weather/cloudy.json | 5 ++++- res/presets/weather/fog.json | 3 ++- res/presets/weather/rain.json | 5 ++++- res/presets/weather/snow.json | 5 ++++- res/presets/weather/thunder.json | 4 +++- res/shaders/clouds.glslv | 2 +- res/shaders/entity.glslv | 2 +- res/shaders/lib/constants.glsl | 1 - res/shaders/lib/sky.glsl | 4 ++-- res/shaders/lib/world_uniforms.glsl | 1 + res/shaders/main.glslv | 2 +- res/shaders/skybox_gen.glslf | 4 +++- res/shaders/translucent.glslv | 2 +- src/graphics/render/CloudsRenderer.cpp | 14 ++++---------- src/graphics/render/CloudsRenderer.hpp | 2 +- src/graphics/render/PrecipitationRenderer.cpp | 2 +- src/graphics/render/Skybox.cpp | 7 +++++-- src/graphics/render/Skybox.hpp | 3 ++- src/graphics/render/WorldRenderer.cpp | 15 ++++++++++++--- src/presets/WeatherPreset.cpp | 6 ++++++ src/presets/WeatherPreset.hpp | 9 +++++++++ src/world/Weather.hpp | 13 +++++++++++++ 22 files changed, 80 insertions(+), 31 deletions(-) diff --git a/res/presets/weather/cloudy.json b/res/presets/weather/cloudy.json index c9af2f0d6..5e11a8ac6 100644 --- a/res/presets/weather/cloudy.json +++ b/res/presets/weather/cloudy.json @@ -1,4 +1,7 @@ { - "clouds": 1.0 + "clouds": 1.0, + "clouds_tint": [0.6, 0.7, 0.8], + "sky_tint": [1.5, 1.5, 1.5], + "min_sky_light": [0.05, 0.07, 0.1] } diff --git a/res/presets/weather/fog.json b/res/presets/weather/fog.json index 6f65685c8..458283969 100644 --- a/res/presets/weather/fog.json +++ b/res/presets/weather/fog.json @@ -2,5 +2,6 @@ "fog_opacity": 0.98, "fog_dencity": 3.6, "fog_curve": 0.25, - "clouds": 0.9 + "clouds": 0.9, + "min_sky_light": [0.0, 0.0, 0.0] } diff --git a/res/presets/weather/rain.json b/res/presets/weather/rain.json index 184a80f0d..90e0512e9 100644 --- a/res/presets/weather/rain.json +++ b/res/presets/weather/rain.json @@ -19,5 +19,8 @@ "fog_opacity": 0.5, "fog_dencity": 1.7, "fog_curve": 0.5, - "clouds": 0.9 + "clouds": 0.96, + "sky_tint": [2.0, 2.0, 2.0], + "clouds_tint": [0.6, 0.7, 0.8], + "min_sky_light": [0.05, 0.07, 0.1] } diff --git a/res/presets/weather/snow.json b/res/presets/weather/snow.json index da80a8560..18763aa85 100644 --- a/res/presets/weather/snow.json +++ b/res/presets/weather/snow.json @@ -11,5 +11,8 @@ "fog_opacity": 0.8, "fog_dencity": 2.5, "fog_curve": 0.5, - "clouds": 0.5 + "clouds": 1.0, + "sky_tint": [1.9, 1.9, 1.9], + "clouds_tint": [0.7, 0.8, 0.9], + "min_sky_light": [0.05, 0.07, 0.1] } diff --git a/res/presets/weather/thunder.json b/res/presets/weather/thunder.json index d2a107f93..0a6f97c96 100644 --- a/res/presets/weather/thunder.json +++ b/res/presets/weather/thunder.json @@ -19,5 +19,7 @@ "fog_dencity": 2.0, "fog_curve": 0.5, "clouds": 0.7, - "thunder_rate": 0.1 + "thunder_rate": 0.1, + "clouds_tint": [0.3, 0.4, 0.5], + "min_sky_light": [0.0, 0.0, 0.0] } diff --git a/res/shaders/clouds.glslv b/res/shaders/clouds.glslv index 6c36aa464..0b9c17774 100644 --- a/res/shaders/clouds.glslv +++ b/res/shaders/clouds.glslv @@ -31,7 +31,7 @@ void main() { a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime); + vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime, u_minSkyLight); a_skyLight = skyLightColor.rgb*v_light.a; mat4 viewmodel = u_view * u_model; diff --git a/res/shaders/entity.glslv b/res/shaders/entity.glslv index d50cd0075..8f534a6dc 100644 --- a/res/shaders/entity.glslv +++ b/res/shaders/entity.glslv @@ -28,7 +28,7 @@ void main() { a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime); + vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime, u_minSkyLight); a_color.rgb = max(a_color.rgb, skyLightColor.rgb * v_light.a) * v_color; a_color.a = u_opacity; diff --git a/res/shaders/lib/constants.glsl b/res/shaders/lib/constants.glsl index 1c2f4062b..a8a9a4bb3 100644 --- a/res/shaders/lib/constants.glsl +++ b/res/shaders/lib/constants.glsl @@ -10,7 +10,6 @@ // lighting #define SKY_LIGHT_MUL 2.5 #define SKY_LIGHT_TINT (vec3(1.0, 0.75, 0.6) * 2.0) -#define MIN_SKY_LIGHT vec3(0.2, 0.25, 0.33) // fog #define FOG_POS_SCALE vec3(1.0, 0.2, 1.0) diff --git a/res/shaders/lib/sky.glsl b/res/shaders/lib/sky.glsl index 97203286b..cfdbc3f2b 100644 --- a/res/shaders/lib/sky.glsl +++ b/res/shaders/lib/sky.glsl @@ -3,12 +3,12 @@ #include -vec3 pick_sky_color(samplerCube cubemap, float dayTime) { +vec3 pick_sky_color(samplerCube cubemap, float dayTime, vec3 minSkyLight) { float elevation = sin(dayTime * PI2) * 0.2; vec3 skyLightColor = texture(cubemap, vec3(0.0f, elevation, -0.4f)).rgb; skyLightColor *= SKY_LIGHT_TINT; skyLightColor = min(vec3(1.0f), skyLightColor * SKY_LIGHT_MUL); - skyLightColor = max(MIN_SKY_LIGHT, skyLightColor); + skyLightColor = max(minSkyLight, skyLightColor); return skyLightColor; } diff --git a/res/shaders/lib/world_uniforms.glsl b/res/shaders/lib/world_uniforms.glsl index 20c8f529e..96dde0110 100644 --- a/res/shaders/lib/world_uniforms.glsl +++ b/res/shaders/lib/world_uniforms.glsl @@ -11,5 +11,6 @@ uniform float u_timer; uniform samplerCube u_skybox; uniform vec3 u_torchlightColor; uniform float u_torchlightDistance; +uniform vec3 u_minSkyLight; #endif // GLSL_WORLD_UNIFORMS_ diff --git a/res/shaders/main.glslv b/res/shaders/main.glslv index 8cc7a7637..08cc6469e 100644 --- a/res/shaders/main.glslv +++ b/res/shaders/main.glslv @@ -27,7 +27,7 @@ void main() { a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime); + vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime, u_minSkyLight); a_skyLight = skyLightColor.rgb*v_light.a; mat4 viewmodel = u_view * u_model; diff --git a/res/shaders/skybox_gen.glslf b/res/shaders/skybox_gen.glslf index 583104ebb..b6f2b7ffb 100644 --- a/res/shaders/skybox_gen.glslf +++ b/res/shaders/skybox_gen.glslf @@ -241,6 +241,8 @@ uniform vec3 u_xaxis; uniform vec3 u_yaxis; uniform vec3 u_zaxis; uniform vec3 u_lightDir; +uniform vec3 u_tint; +uniform vec3 u_hightlight; uniform int u_quality; uniform float u_mie; uniform float u_fog; @@ -295,5 +297,5 @@ void main() { col = 1.0 - exp(-col); col = min(col, vec3(1.0)); // Output to screen - f_color = vec4(col, 1.0); + f_color = vec4(col * u_tint + u_hightlight, 1.0); } diff --git a/res/shaders/translucent.glslv b/res/shaders/translucent.glslv index 16cc8c4e3..d9d8031c3 100644 --- a/res/shaders/translucent.glslv +++ b/res/shaders/translucent.glslv @@ -27,7 +27,7 @@ void main() { a_texCoord = v_texCoord; a_dir = a_modelpos.xyz - u_cameraPos; - vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime); + vec3 skyLightColor = pick_sky_color(u_skybox, u_dayTime, u_minSkyLight); a_skyLight = skyLightColor.rgb*v_light.a; mat4 viewmodel = u_view * u_model; diff --git a/src/graphics/render/CloudsRenderer.cpp b/src/graphics/render/CloudsRenderer.cpp index eea8240be..5253004f6 100755 --- a/src/graphics/render/CloudsRenderer.cpp +++ b/src/graphics/render/CloudsRenderer.cpp @@ -218,7 +218,7 @@ CloudsRenderer::CloudsRenderer() { CloudsMap map({w, h, d}, voxels); volumeRenderer.build(map); - testMeshes[layer] = std::make_unique>(volumeRenderer.createMesh()); + meshes[layer] = std::make_unique>(volumeRenderer.createMesh()); } } @@ -232,13 +232,7 @@ void CloudsRenderer::draw( const Camera& camera, int quality ) { - float clouds = weather.clouds(); - shader.uniform4f( - "u_tint", - glm::vec4( - 1.0f - clouds * 0.5, 1.0f - clouds * 0.45, 1.0f - clouds * 0.4, 1.0f - ) - ); + shader.uniform4f("u_tint", glm::vec4(weather.cloudsTint(), 1.0f)); float scale = 8; float totalWidth = WIDTH * scale; @@ -248,7 +242,7 @@ void CloudsRenderer::draw( int cellZ = glm::floor(camera.position.z / totalDepth + 0.5f); float speed = 4.0f; - for (int i = 0; i < std::min(quality, testMeshes.size()); i++) { + for (int i = 0; i < std::min(quality, meshes.size()); i++) { float speedX = glm::sin(i * 0.3f + 0.4f) * speed / (i + 1); float speedZ = -glm::cos(i * 0.3f + 0.4f) * speed / (i + 1); for (int x = -2; x <= 2; x++) { @@ -268,7 +262,7 @@ void CloudsRenderer::draw( shader.uniform1f("u_fogFactor", fogFactor * 0.03f); shader.uniform1f("u_fogCurve", 0.7f - 0.3f); shader.uniformMatrix("u_model", matrix); - testMeshes[i]->draw(); + meshes[i]->draw(); } } } diff --git a/src/graphics/render/CloudsRenderer.hpp b/src/graphics/render/CloudsRenderer.hpp index d5f379749..736acebd9 100755 --- a/src/graphics/render/CloudsRenderer.hpp +++ b/src/graphics/render/CloudsRenderer.hpp @@ -22,5 +22,5 @@ public: int quality ); private: - std::array>, 2> testMeshes; + std::array>, 2> meshes; }; diff --git a/src/graphics/render/PrecipitationRenderer.cpp b/src/graphics/render/PrecipitationRenderer.cpp index 341d94f88..c566a06d2 100644 --- a/src/graphics/render/PrecipitationRenderer.cpp +++ b/src/graphics/render/PrecipitationRenderer.cpp @@ -151,7 +151,7 @@ void PrecipitationRenderer::render( glm::cross(glm::vec3(0, 1, 0), face.right), FACE_SIZE, light_at(chunks, pos.x, y, pos.z), - glm::vec3(3.0f), + glm::vec3(1.0f), calc_uv(pos, face.right, timer, weather) ); } diff --git a/src/graphics/render/Skybox.cpp b/src/graphics/render/Skybox.cpp index b5c5191f2..c546c62e3 100644 --- a/src/graphics/render/Skybox.cpp +++ b/src/graphics/render/Skybox.cpp @@ -170,7 +170,7 @@ void Skybox::draw( drawStars(angle, opacity); } -void Skybox::refresh(const DrawContext& pctx, float t, float mie, uint quality) { +void Skybox::refresh(const DrawContext& pctx, float t, float mie, const glm::vec3& tint, const glm::vec3& hightlight, uint quality) { frameid++; float dayTime = t; DrawContext ctx = pctx.sub(); @@ -201,11 +201,13 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, uint quality) shader.uniform1i("u_quality", quality); shader.uniform1f("u_mie", mie); + shader.uniform3f("u_tint", tint); + shader.uniform3f("u_hightlight", hightlight); shader.uniform1f("u_fog", mie - 1.0f); shader.uniform3f("u_lightDir", lightDir); shader.uniform1f("u_dayTime", dayTime); - if (glm::abs(mie-prevMie) + glm::abs(t-prevT) >= 0.01) { + if (glm::abs(mie-prevMie) + glm::abs(t-prevT) + glm::abs(prevHighlight.r - hightlight.r) >= 0.01) { for (uint face = 0; face < 6; face++) { refreshFace(face, cubemap); } @@ -215,6 +217,7 @@ void Skybox::refresh(const DrawContext& pctx, float t, float mie, uint quality) } prevMie = mie; prevT = t; + prevHighlight = hightlight; cubemap->unbind(); glActiveTexture(GL_TEXTURE0); diff --git a/src/graphics/render/Skybox.hpp b/src/graphics/render/Skybox.hpp index f2b81876c..d2dde6f5e 100644 --- a/src/graphics/render/Skybox.hpp +++ b/src/graphics/render/Skybox.hpp @@ -49,6 +49,7 @@ class Skybox { float prevMie = -1.0f; float prevT = -1.0f; float sunAltitude = 45.0f; + glm::vec3 prevHighlight {1.0f}; glm::mat4 rotation; void drawStars(float angle, float opacity); @@ -68,7 +69,7 @@ public: float fog ); - void refresh(const DrawContext& pctx, float t, float mie, uint quality); + void refresh(const DrawContext& pctx, float t, float mie, const glm::vec3& tint, const glm::vec3& hightlight, uint quality); void bind() const; void unbind() const; bool isReady() const { diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index aef2b8674..4157eeb98 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -126,6 +126,7 @@ static void setup_weather(Shader& shader, const Weather& weather) { shader.uniform1f("u_weatherFogOpacity", weather.fogOpacity()); shader.uniform1f("u_weatherFogDencity", weather.fogDencity()); shader.uniform1f("u_weatherFogCurve", weather.fogCurve()); + shader.uniform3f("u_minSkyLight", weather.minSkyLight()); } static void setup_camera(Shader& shader, const Camera& camera) { @@ -348,7 +349,15 @@ void WorldRenderer::renderFrame( clouds = glm::max(worldInfo.fog, clouds); float mie = 1.0f + glm::max(worldInfo.fog, clouds * 0.5f) * 2.0f; - skybox->refresh(pctx, worldInfo.daytime, mie, 4); + float random = rand() / static_cast(RAND_MAX); + skybox->refresh( + pctx, + worldInfo.daytime, + mie, + weather.skyTint(), + weather.highlight * random, + 4 + ); chunksRenderer->update(); @@ -402,15 +411,14 @@ void WorldRenderer::renderFrame( linesShader.uniformMatrix("u_projview", projView); lineBatch->flush(); + skybox->bind(); // Translucent blocks { auto sctx = ctx.sub(); sctx.setCullFace(true); - skybox->bind(); translucentShader.use(); setupWorldShader(translucentShader, camera, settings, fogFactor); chunksRenderer->drawSortedMeshes(camera, translucentShader); - skybox->unbind(); } // Weather effects @@ -429,6 +437,7 @@ void WorldRenderer::renderFrame( precipitation->render(camera, *weather); } } + skybox->unbind(); glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/src/presets/WeatherPreset.cpp b/src/presets/WeatherPreset.cpp index 6ae0bae7e..3350e2d70 100644 --- a/src/presets/WeatherPreset.cpp +++ b/src/presets/WeatherPreset.cpp @@ -23,6 +23,9 @@ dv::value WeatherPreset::serialize() const { root["fog_opacity"] = fogOpacity; root["fog_dencity"] = fogDencity; root["fog_curve"] = fogCurve; + root["sky_tint"] = dv::to_value(skyTint); + root["clouds_tint"] = dv::to_value(cloudsTint); + root["min_sky_light"] = dv::to_value(minSkyLight); root["clouds"] = clouds; root["thunder_rate"] = thunderRate; @@ -51,6 +54,9 @@ void WeatherPreset::deserialize(const dv::value& src) { src.at("fog_opacity").get(fogOpacity); src.at("fog_dencity").get(fogDencity); src.at("fog_curve").get(fogCurve); + dv::get_vec(src, "sky_tint", skyTint); + dv::get_vec(src, "clouds_tint", cloudsTint); + dv::get_vec(src, "min_sky_light", minSkyLight); src.at("clouds").get(clouds); src.at("thunder_rate").get(thunderRate); } diff --git a/src/presets/WeatherPreset.hpp b/src/presets/WeatherPreset.hpp index e49d1f3cb..d66ef0f63 100644 --- a/src/presets/WeatherPreset.hpp +++ b/src/presets/WeatherPreset.hpp @@ -60,6 +60,15 @@ struct WeatherPreset : Serializable { /// @brief Weather effects intensity float intensity = 0.0f; + /// @brief Skybox color multiplier + glm::vec3 skyTint {1.0f, 1.0f, 1.0f}; + + /// @brief Clouds color multiplier + glm::vec3 cloudsTint {1.0f, 1.0f, 1.0f}; + + /// @brief Minimal sky-emitted lights (moon light) + glm::vec3 minSkyLight {0.2f, 0.25f, 0.33f}; + dv::value serialize() const override; void deserialize(const dv::value& src) override; }; diff --git a/src/world/Weather.hpp b/src/world/Weather.hpp index 6d8af0bb2..3084bf99e 100644 --- a/src/world/Weather.hpp +++ b/src/world/Weather.hpp @@ -12,6 +12,7 @@ struct Weather : Serializable { std::string nameB; float t = 1.0f; float speed = 0.0f; + glm::vec3 highlight {}; void update(float delta) { t += delta * speed; @@ -51,6 +52,18 @@ struct Weather : Serializable { return b.clouds * sqrtT + a.clouds * (1.0f - sqrtT); } + glm::vec3 skyTint() const { + return b.skyTint * t + a.skyTint * (1.0f - t); + } + + glm::vec3 cloudsTint() const { + return b.cloudsTint * t + a.cloudsTint * (1.0f - t); + } + + glm::vec3 minSkyLight() const { + return b.minSkyLight * t + a.minSkyLight * (1.0f - t); + } + dv::value serialize() const override; void deserialize(const dv::value& src) override; };