From 74d1e61813edc3fadf4ac79ec8c63fcc8d2e91fa Mon Sep 17 00:00:00 2001 From: chexit Date: Thu, 29 Oct 2026 23:22:19 +0300 Subject: [PATCH] HD clouds: noise scales that divide the camera's 65536-block wrap, so the clouds and their shadows no longer jump at x or z = 0 Co-Authored-By: Claude Opus 5.5 --- crates/horizon-client/src/gfx/hd/cloud_common.wgsl | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/horizon-client/src/gfx/hd/cloud_common.wgsl b/crates/horizon-client/src/gfx/hd/cloud_common.wgsl index 393ea564b..e2352f008 100644 --- a/crates/horizon-client/src/gfx/hd/cloud_common.wgsl +++ b/crates/horizon-client/src/gfx/hd/cloud_common.wgsl @@ -21,6 +21,8 @@ fn dampen(x: f32) -> f32 { } // Where a camera-relative point lies in the world's cloud pattern (the wind moves the pattern). +// The camera's x, z come wrapped to 65536 blocks: every noise scale below must divide that (powers +// of two), or the pattern jumps where the wrap happens (at x or z = 0). fn cloud_xz(pos: vec3) -> vec2 { return vec2(pos.x + frame.cloud_cam.x, pos.z + frame.cloud_cam.y) + vec2(0.8, 0.6) * (CLOUD_WIND * frame.clouds.w); @@ -33,8 +35,8 @@ fn cloud_density(pos: vec3, detail: f32) -> f32 { let h = (pos.y - frame.clouds.x) / frame.clouds.y; if h <= 0.0 || h >= 1.0 { return 0.0; } let w = cloud_xz(pos); - let cover = textureSampleLevel(noise2, repeat_s, w / 16000.0, 0.0).r; - let shape = textureSampleLevel(noise2, repeat_s, w / 3000.0, 0.0).g; + let cover = textureSampleLevel(noise2, repeat_s, w / 16384.0, 0.0).r; + let shape = textureSampleLevel(noise2, repeat_s, w / 4096.0, 0.0).g; let cu = mix(0.56, 0.80, cover) + frame.cloud_cam.z; var d = linear_step(1.0 - cu, 1.0, shape); // Carve an egg shape, thin out the bottom. @@ -43,9 +45,9 @@ fn cloud_density(pos: vec3, detail: f32) -> f32 { if d < 0.002 { return 0.0; } if detail > 0.0 { let p3 = vec3(w.x, pos.y, w.y); - let warp = (textureSampleLevel(noise3, repeat_s, p3 / 1100.0, 0.0).b - 0.5) * 0.4; - let w0 = 1.0 - textureSampleLevel(noise3, repeat_s, p3 / 420.0 + vec3(warp), 0.0).r; - let w1 = 1.0 - textureSampleLevel(noise3, repeat_s, p3 / 90.0 + vec3(warp * 3.0), 0.0).g; + let warp = (textureSampleLevel(noise3, repeat_s, p3 / 1024.0, 0.0).b - 0.5) * 0.4; + let w0 = 1.0 - textureSampleLevel(noise3, repeat_s, p3 / 512.0 + vec3(warp), 0.0).r; + let w1 = 1.0 - textureSampleLevel(noise3, repeat_s, p3 / 64.0 + vec3(warp * 3.0), 0.0).g; let fade = 0.20 * smoothstep(0.85, 1.0, 1.0 - h) - 0.35 * smoothstep(0.05, 0.5, h) + 0.6; d -= 0.55 * w0 * w0 * dampen(1.0 - d); d -= 0.45 * w1 * w1 * dampen(1.0 - d) * fade;