From aec43c0bcf721cf3f6a40ec64dbf0509474be58a Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Tue, 9 Sep 2025 18:41:45 -0500 Subject: [PATCH] cloud rendering --- client/shaders/sky.fs | 71 +++++++++++++++++++++++++++++++++++++++++++ client/sky/Sky.cpp | 5 +++ client/sky/Sky.hpp | 1 + 3 files changed, 77 insertions(+) diff --git a/client/shaders/sky.fs b/client/shaders/sky.fs index e6cda6a..aa4325f 100644 --- a/client/shaders/sky.fs +++ b/client/shaders/sky.fs @@ -22,6 +22,7 @@ uniform vec3 moonColor; uniform float moonIntensity; uniform float moonPhase; uniform float starsIntensity; +uniform float time; // Output fragment color out vec4 finalColor; @@ -31,6 +32,40 @@ float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); } +// Noise function for clouds +float noise(vec2 p) { + vec2 i = floor(p); + vec2 f = fract(p); + + // Four corners in 2D of a tile + float a = hash(i); + float b = hash(i + vec2(1.0, 0.0)); + float c = hash(i + vec2(0.0, 1.0)); + float d = hash(i + vec2(1.0, 1.0)); + + // Smooth interpolation + vec2 u = f * f * (3.0 - 2.0 * f); + + return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; +} + +// Fractal brownian motion for cloud shapes +float fbm(vec2 p) { + float value = 0.0; + float amplitude = 0.5; + float frequency = 2.0; + + for (int i = 0; i < 3; i++) { + value += amplitude * noise(p * frequency); + amplitude *= 0.5; + frequency *= 2.0; + } + + return value; +} + + + void main() { // Normalize the world position to get direction from center @@ -42,6 +77,42 @@ void main() // Interpolate between horizon and zenith colors vec3 skyColor = mix(horizonColor, zenithColor, gradientFactor); + // Simple cloud layer (only during day) + if (direction.y > 0.1 && sunIntensity > 0.2) { + // Map direction to 2D cloud coordinates + vec2 cloudCoord = direction.xz / max(direction.y, 0.001) * 0.5; + + // Animate clouds + cloudCoord += vec2(time * 0.02, time * 0.01); + + // Generate cloud pattern using multiple layers of noise + float cloudNoise = 0.0; + cloudNoise += fbm(cloudCoord * 2.0) * 0.5; + cloudNoise += fbm(cloudCoord * 5.0) * 0.25; + cloudNoise += fbm(cloudCoord * 11.0) * 0.125; + + // Shape the clouds + float cloudDensity = smoothstep(0.4, 0.6, cloudNoise); + + // Fade clouds at horizon + cloudDensity *= smoothstep(0.0, 0.3, direction.y); + + if (cloudDensity > 0.01) { + // Simple cloud lighting + float lightness = 0.7 + 0.3 * sunIntensity; + + // Make clouds slightly bluish in shadow, whiter in light + vec3 cloudColor = mix( + vec3(0.7, 0.75, 0.85), // Shadow color + vec3(1.0, 1.0, 1.0), // Lit color + lightness + ); + + // Mix clouds with sky + skyColor = mix(skyColor, cloudColor, cloudDensity * 0.8); + } + } + // Add stars (only visible at night) if (starsIntensity > 0.01 && direction.y > -0.1) { // Don't render stars below horizon // Create a simple star field using noise diff --git a/client/sky/Sky.cpp b/client/sky/Sky.cpp index b18e4fd..07673f8 100644 --- a/client/sky/Sky.cpp +++ b/client/sky/Sky.cpp @@ -37,6 +37,7 @@ Sky::Sky() moonIntensityLoc = GetShaderLocation(skyShader, "moonIntensity"); moonPhaseLoc = GetShaderLocation(skyShader, "moonPhase"); starsIntensityLoc = GetShaderLocation(skyShader, "starsIntensity"); + timeLoc = GetShaderLocation(skyShader, "time"); // Assign shader to sky model skyModel.materials[0].shader = skyShader; @@ -290,6 +291,10 @@ void Sky::renderSkybox(const Camera3D& camera) { SetShaderValue(skyShader, moonPhaseLoc, &moon.phase, SHADER_UNIFORM_FLOAT); SetShaderValue(skyShader, starsIntensityLoc, &starsIntensity, SHADER_UNIFORM_FLOAT); + // Pass current time for cloud animation + float currentTime = GetTime(); + SetShaderValue(skyShader, timeLoc, ¤tTime, SHADER_UNIFORM_FLOAT); + // Draw the sky dome with shader DrawModel(skyModel, {0, 0, 0}, 1.0f, WHITE); } else { diff --git a/client/sky/Sky.hpp b/client/sky/Sky.hpp index 344bf72..b83219e 100644 --- a/client/sky/Sky.hpp +++ b/client/sky/Sky.hpp @@ -50,6 +50,7 @@ private: int moonIntensityLoc; int moonPhaseLoc; int starsIntensityLoc; + int timeLoc; public: Sky();