From 48160b730f9aafd25be8986179fadc6a51ddee53 Mon Sep 17 00:00:00 2001 From: Richard Zink Date: Wed, 7 Oct 2026 20:09:08 +0200 Subject: [PATCH] Dark night sky + slow star twinkle + moonlit clouds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clouds3d: - Star twinkle: 3 Hz ±45% -> 0.5 Hz ±15% (gentle scintillation instead of static-like flickering) - Night darkening: applied only to sky pixels via the cloud mask, not to clouds. The darkening factor jumped 0.45 -> 0.85 so the night sky really does go black around moonlit clouds. Clouds keep their uLight-tinted colour so they remain visible. clouds2d: - Same darkening approach but via multiplicative factor (no cloud mask in the 2D shader): col *= 1 - nightFactor * 0.7 --- vendor/clouds2d.js | 4 +++- vendor/clouds3d.js | 29 ++++++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/vendor/clouds2d.js b/vendor/clouds2d.js index f562f1d..6ae0acd 100644 --- a/vendor/clouds2d.js +++ b/vendor/clouds2d.js @@ -110,7 +110,9 @@ var FRAG_SRC = [ // Night darkening, driven by sun altitude (not uDayProgress // which is a 24h clock progress, not "is it night") 'float nightFactor = smoothstep(0.05, -0.15, uSunAlt);', - 'col = mix(col, mix(uBg, col, 0.4), nightFactor * 0.45);', + // Stronger than clouds3d because there's no cloud-mask + // blending here — just multiply. + 'col *= 1.0 - nightFactor * 0.7;', 'gl_FragColor = vec4(col, 1.0);', '}' ].join('\n'); diff --git a/vendor/clouds3d.js b/vendor/clouds3d.js index 595eb14..a57db79 100644 --- a/vendor/clouds3d.js +++ b/vendor/clouds3d.js @@ -117,16 +117,18 @@ var FRAG_SRC = [ // Star field: project ray onto a far sphere, hash-grid for // positions. Visible above the horizon at night with a small // twinkle. - 'float starField(vec3 r) {', - 'vec3 sp = r * 220.0;', - 'vec3 sf = floor(sp);', - 'vec3 sfp = fract(sp) - 0.5;', - 'float h = hash3(sf);', - 'float starD = length(sfp);', - 'float mask = step(0.985, h) * smoothstep(0.35, 0.0, starD);', - 'float twinkle = 0.55 + 0.45 * sin(uTime * 3.0 + h * 47.0);', - 'return mask * twinkle;', - '}', +'float starField(vec3 r) {', + 'vec3 sp = r * 220.0;', + 'vec3 sf = floor(sp);', + 'vec3 sfp = fract(sp) - 0.5;', + 'float h = hash3(sf);', + 'float starD = length(sfp);', + 'float mask = step(0.985, h) * smoothstep(0.35, 0.0, starD);', + // Slow, subtle twinkle (0.5 Hz, ±15%). 3 Hz was too fast + // and looked like static instead of gentle scintillation. + 'float twinkle = 0.85 + 0.15 * sin(uTime * 0.5 + h * 47.0);', + 'return mask * twinkle;', + '}', 'void main() {', 'vec2 uv = (gl_FragCoord.xy / uResolution.xy) * 2.0 - 1.0;', 'uv.x *= uResolution.x / uResolution.y;', @@ -184,7 +186,12 @@ var FRAG_SRC = [ // Night darkening — driven by sun altitude, not uDayProgress // (uDayProgress is the 0..1 clock progress through 24h, which // is not the same as 'is it night'). - 'col = mix(col, mix(uBg, col, 0.4), nightFactor * 0.45);', + // Only darkens the sky, NOT the clouds — we want them to stay + // moon-lit (their colour came from uLight) while the sky around + // them goes dark. The cloud mask 'cloud' tells us how much of + // this pixel is cloud, so fully cloudy pixels keep their colour. + 'float skyDarkness = nightFactor * 0.85;', + 'col = mix(col, col * (1.0 - skyDarkness), 1.0 - cloud);', 'gl_FragColor = vec4(col, 1.0);', '}' ].join('\n');