From a3b06062ff2376bc98cebb02408833fc9569c7c7 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Thu, 11 Jun 2026 20:09:03 +0100 Subject: [PATCH] Improve rain scene --- src/scenes/rain/rain-scene.ts | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/scenes/rain/rain-scene.ts b/src/scenes/rain/rain-scene.ts index 6198fe3..03c6db9 100644 --- a/src/scenes/rain/rain-scene.ts +++ b/src/scenes/rain/rain-scene.ts @@ -9,11 +9,9 @@ const WIND_SLANT = 0.2; export class RainScene implements Scene { private droplets: Array = []; - private lights = [ - new CircleLight(vec2.create(), rgb255(184, 41, 255), 1.5), - new CircleLight(vec2.create(), rgb255(255, 31, 109), 1.5), - new CircleLight(vec2.create(), rgb255(64, 110, 255), 1.5), - ]; + // The moon: a single pale, cold light hanging high in the sky and the scene's + // only light source — the falling rain only shows where its streaks catch it. + private moon = new CircleLight(vec2.create(), rgb255(200, 214, 255), 2.5); private overlay: HTMLDivElement; public insights?: any; @@ -41,14 +39,18 @@ export class RainScene implements Scene { }, { ...CircleLight.descriptor, - shaderCombinationSteps: [0, 3], + shaderCombinationSteps: [0, 1], }, ], this.drawNextFrame.bind(this), { - backgroundColor: rgb(0.5, 0.5, 0.5), - ambientLight: rgb(0.2, 0.2, 0.23), + // A dark night sky so the moon is the dominant light. + backgroundColor: rgb(0.09, 0.12, 0.19), + ambientLight: rgb(0.2, 0.22, 0.28), enableHighDpiRendering: true, + // Keep most of the previous frame each render so the droplets smear + // into long streaks of rain. + motionBlur: 0.9, // More, smaller tiles keep the droplet count per tile low. tileMultiplier: 12, } @@ -70,19 +72,17 @@ export class RainScene implements Scene { const viewAreaSize = renderer.viewAreaSize; - // each light sweeps within its own third of the screen - this.lights.forEach((light, i) => { - vec2.set( - light.center, - viewAreaSize.x * - ((i + 0.5) / 3 + (1 / 6) * Math.sin(currentTime / 900 + (i * Math.PI * 2) / 3)), - 0 - ); - }); + // The moon drifts back and forth along the top edge; the rain falls past + // it and lights up. + vec2.set( + this.moon.center, + viewAreaSize.x * (0.5 + 0.5 * Math.sin(currentTime / 2500)), + viewAreaSize.y * 0.95 + ); this.droplets.forEach((d) => d.animate(currentTime, viewAreaSize, WIND_SLANT)); - [...this.droplets.map((d) => d.drawable), ...this.lights].forEach((d) => + [...this.droplets.map((d) => d.drawable), this.moon].forEach((d) => renderer.addDrawable(d) );