Permanent above-clouds cruise + more structure

- Remove dive component from camY. Was mix(2.0, 1.2, diveT)
  (occasional dips into cloud top); now fixed at 2.2, always above
  the y=1.5 cloud ceiling. Cloud deck always visible below.
- WEATHER_DENSITY bumped again: sunny 0.55->0.65, cloudy 0.85->0.90,
  night 0.65->0.75. Even 'sunny' is now a partly-cloudy sky.
- clouds3d: third fBm detail layer at 3.2x frequency (was 2 layers).
  Contributions: base 1.0, mid 0.30, fine 0.12. Combined with the
  tighter smoothstep (0.18 -> 0.16) the silhouettes have wispier,
  more interesting edges instead of soft blobs.
- Same density bump in clouds2d for consistency.
This commit is contained in:
Richard Zink committed 2026-10-07 20:05:39 +02:00
1 parent 9a933b3dc4
commit 42c078a407
2 files changed
+19 -21

No files matched your search

+3 -3
View File
@@ -122,10 +122,10 @@ function hex(rgb) {
} }
var WEATHER_DENSITY = { var WEATHER_DENSITY = {
sunny: 0.55, sunny: 0.65,
cloudy: 0.85, cloudy: 0.90,
stormy: 1.00, stormy: 1.00,
night: 0.65 night: 0.75
}; };
// Load the noise image and upload it as a REPEAT-wrapped texture. // Load the noise image and upload it as a REPEAT-wrapped texture.
+16 -18
View File
@@ -97,21 +97,23 @@ var FRAG_SRC = [
'}', '}',
'return v;', 'return v;',
'}', '}',
// Density at a point in the cloud layer. Two fBm layers: the // Density at a point in the cloud layer. Three fBm layers: the
// base one at low frequency gives the large puffs, the detail // base one at low frequency gives the large puffs, the mid
// layer at higher frequency breaks up the silhouette so clouds // detail layer breaks up the silhouette, the fine layer adds
// don't look like soft blobs. // wispy edges. Combined the result has more visual interest than
// a single fBm.
'float cloudDensity(vec3 p, float baseThresh) {', 'float cloudDensity(vec3 p, float baseThresh) {',
'float n = fbm3(p * 0.35 + vec3(0.0, 0.0, uTime * 0.06));', 'float n = fbm3(p * 0.35 + vec3(0.0, 0.0, uTime * 0.06));',
'float d = fbm3(p * 1.4 + vec3(uTime * 0.04, 7.3, uTime * 0.03));', 'float d = fbm3(p * 1.4 + vec3(uTime * 0.04, 7.3, uTime * 0.03));',
'n = n + d * 0.18;', 'float f = fbm3(p * 3.2 + vec3(2.1, uTime * 0.02, 5.7));',
'n = n + d * 0.30 + f * 0.12;',
// Cloud layer thickness: between y=-0.3 (deck bottom) // Cloud layer thickness: between y=-0.3 (deck bottom)
// and y=1.5 (top), densest in the middle. // and y=1.5 (top), densest in the middle.
'float h = clamp((p.y + 0.3) / 1.8, 0.0, 1.0);', 'float h = clamp((p.y + 0.3) / 1.8, 0.0, 1.0);',
'float profile = 4.0 * h * (1.0 - h); // bell curve', 'float profile = 4.0 * h * (1.0 - h); // bell curve',
'profile = max(profile, 0.0);', 'profile = max(profile, 0.0);',
// Tighter smoothstep so the cloud edges have more detail. // Tighter smoothstep so the cloud edges have more detail.
'return smoothstep(baseThresh, baseThresh + 0.18, n) * profile;', 'return smoothstep(baseThresh, baseThresh + 0.16, n) * profile;',
'}', '}',
// Star field: project ray onto a far sphere, hash-grid for // Star field: project ray onto a far sphere, hash-grid for
// positions. Visible above the horizon at night with a small // positions. Visible above the horizon at night with a small
@@ -129,16 +131,12 @@ var FRAG_SRC = [
'void main() {', 'void main() {',
'vec2 uv = (gl_FragCoord.xy / uResolution.xy) * 2.0 - 1.0;', 'vec2 uv = (gl_FragCoord.xy / uResolution.xy) * 2.0 - 1.0;',
'uv.x *= uResolution.x / uResolution.y;', 'uv.x *= uResolution.x / uResolution.y;',
// Camera path: slow drift in X, mostly cruising just above the // Camera path: slow drift in X, cruising just above the cloud deck
// cloud deck like an airliner cockpit. pow(...,n) shapes the // like an airliner cockpit. No dives — we stay above so the
// sin into short dips so we occasionally skim the cloud top. // deck is always visible below us.
'float drift = uTime * uSpeed * 0.45;', 'float drift = uTime * uSpeed * 0.45;',
// pow(...,8) keeps dives rare: most of the time diveT≈0, // Fixed altitude well above the cloud ceiling (y=1.5).
// and only spikes briefly to 1. 'float camY = 2.2;',
'float diveT = pow(0.5 + 0.5 * sin(uTime * 0.10), 8.0);',
// Cruise at y=2.0 (just above cloud ceiling y=1.5), dive to
// y=1.2 — close enough to skim the cloud top, never deep inside.
'float camY = mix(2.0, 1.2, diveT);',
'vec3 ro = vec3(drift, camY, drift * 0.7);', 'vec3 ro = vec3(drift, camY, drift * 0.7);',
// Ray direction: nearly level, like looking out a cockpit // Ray direction: nearly level, like looking out a cockpit
// window. Horizon sits around the middle of the frame. // window. Horizon sits around the middle of the frame.
@@ -238,10 +236,10 @@ function hex(rgb) {
// Higher density across the board so even 'sunny' shows some cloud // Higher density across the board so even 'sunny' shows some cloud
// structure, not just clear sky. Same mapping as clouds2d. // structure, not just clear sky. Same mapping as clouds2d.
var WEATHER_DENSITY = { var WEATHER_DENSITY = {
sunny: 0.55, sunny: 0.65,
cloudy: 0.85, cloudy: 0.90,
stormy: 1.00, stormy: 1.00,
night: 0.65 night: 0.75
}; };
window.clouds3dRender = function(target) { window.clouds3dRender = function(target) {