Improve rain scene

This commit is contained in:
Andras Schmelczer 2026-06-11 20:09:03 +01:00
parent bdbd3f1021
commit a3b06062ff

View file

@ -9,11 +9,9 @@ const WIND_SLANT = 0.2;
export class RainScene implements Scene { export class RainScene implements Scene {
private droplets: Array<DropletWrapper> = []; private droplets: Array<DropletWrapper> = [];
private lights = [ // The moon: a single pale, cold light hanging high in the sky and the scene's
new CircleLight(vec2.create(), rgb255(184, 41, 255), 1.5), // only light source — the falling rain only shows where its streaks catch it.
new CircleLight(vec2.create(), rgb255(255, 31, 109), 1.5), private moon = new CircleLight(vec2.create(), rgb255(200, 214, 255), 2.5);
new CircleLight(vec2.create(), rgb255(64, 110, 255), 1.5),
];
private overlay: HTMLDivElement; private overlay: HTMLDivElement;
public insights?: any; public insights?: any;
@ -41,14 +39,18 @@ export class RainScene implements Scene {
}, },
{ {
...CircleLight.descriptor, ...CircleLight.descriptor,
shaderCombinationSteps: [0, 3], shaderCombinationSteps: [0, 1],
}, },
], ],
this.drawNextFrame.bind(this), this.drawNextFrame.bind(this),
{ {
backgroundColor: rgb(0.5, 0.5, 0.5), // A dark night sky so the moon is the dominant light.
ambientLight: rgb(0.2, 0.2, 0.23), backgroundColor: rgb(0.09, 0.12, 0.19),
ambientLight: rgb(0.2, 0.22, 0.28),
enableHighDpiRendering: true, 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. // More, smaller tiles keep the droplet count per tile low.
tileMultiplier: 12, tileMultiplier: 12,
} }
@ -70,19 +72,17 @@ export class RainScene implements Scene {
const viewAreaSize = renderer.viewAreaSize; const viewAreaSize = renderer.viewAreaSize;
// each light sweeps within its own third of the screen // The moon drifts back and forth along the top edge; the rain falls past
this.lights.forEach((light, i) => { // it and lights up.
vec2.set( vec2.set(
light.center, this.moon.center,
viewAreaSize.x * viewAreaSize.x * (0.5 + 0.5 * Math.sin(currentTime / 2500)),
((i + 0.5) / 3 + (1 / 6) * Math.sin(currentTime / 900 + (i * Math.PI * 2) / 3)), viewAreaSize.y * 0.95
0
); );
});
this.droplets.forEach((d) => d.animate(currentTime, viewAreaSize, WIND_SLANT)); 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) renderer.addDrawable(d)
); );