Airliner cockpit view + night stars

- Cruise altitude lowered to y=2.0 (just above cloud top at y=1.8)
- Look direction nearly level (rd.y ~ -0.05 at horizon line)
- Stars rendered as 3D hash-grid sphere, only above horizon and
  only when uDayProgress < 1 (i.e. at night). Subtle sin twinkle
  keeps them from looking like static dither.
This commit is contained in:
Richard Zink committed 2026-10-07 19:02:06 +02:00
1 parent e80d255d58
commit ee821dd724
1 file changed
+24 -8
+24 -8
View File
@@ -101,20 +101,36 @@ var FRAG_SRC = [
'void main() {',
'vec2 uv = (gl_FragCoord.xy / uResolution.xy) * 2.0 - 1.0;',
'uv.x *= uResolution.x / uResolution.y;',
// Camera path: slow drift in X, mostly above the cloud deck.
// pow(...,n) shapes the sin into short dips, so the view spends
// most of its time at cruising altitude and only briefly skims
// the top of the cloud layer.
// Camera path: slow drift in X, mostly cruising just above the
// cloud deck like an airliner cockpit. pow(...,n) shapes the
// sin into short dips so we occasionally skim the cloud top.
'float drift = uTime * uSpeed * 0.45;',
'float diveT = pow(0.5 + 0.5 * sin(uTime * 0.10), 5.0);',
'float camY = mix(2.6, 0.9, diveT);',
// Cloud layer tops around y≈1.8. Cruise just above it.
'float camY = mix(2.0, 0.9, diveT);',
'vec3 ro = vec3(drift, camY, drift * 0.7);',
// Ray direction: tilt down a bit more so the cloud deck fills
// the lower frame when we're above it.
'vec3 rd = normalize(vec3(uv.x * 0.55, -0.35 + uv.y * 0.30, 1.0));',
// Ray direction: nearly level, like looking out a cockpit
// window. Horizon sits around the middle of the frame.
'vec3 rd = normalize(vec3(uv.x * 0.55, -0.05 + uv.y * 0.35, 1.0));',
// Sky gradient based on ray Y (background).
'float skyT = clamp(rd.y * 0.7 + 0.5, 0.0, 1.0);',
'vec3 col = mix(uBg, uSky, skyT);',
// Stars: project ray onto a far sphere, hash-grid for star
// positions. Only visible above the horizon and at night,
// with a small twinkle so they don't look like a static
// dither pattern.
'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 stars = starField(rd) * smoothstep(0.05, 0.35, rd.y) * (1.0 - uDayProgress);',
'col = mix(col, uLight, clamp(stars, 0.0, 1.0) * 0.9);',
// Density threshold: weather 'sunny' -> high (sparse clouds),
// 'stormy' -> low (overcast deck).
'float baseThresh = mix(0.72, 0.40, uDensity);',