How Cloudfall works
Every sound you hear and every drop you see is generated in your browser, in real time. Nothing is a recording, nothing is a video, and nothing loops. Here is how each part of that is done — and where it falls short.
The sound is synthesized, not sampled
There are no audio files in Cloudfall. Rain, wind and ocean are built from noise generated in the browser and shaped by filters, which buys three things a sample library cannot.
It never repeats. Sample-based rain gives itself away within a minute or two — you start hearing the seam. Here every layer runs on a buffer of a different length at a rate that shares no common factor with the others, so the combined texture has no period at all.
It responds continuously. Turning rainfall up does not crossfade to a heavier recording; it opens a filter, lifts a low shelf, pushes the droplet layers forward and raises the level together. And because every node belongs to us, the signal is reachable by an analyser — which is what makes the visuals genuinely reactive rather than decorated with a guess.
Amplitude is not loudness. Mapping a rainfall slider straight to gain leaves the bottom half of its travel sounding almost unchanged, because halving amplitude is only about six decibels. The curve is deliberately bent so the quiet end of the range is where the ear can still hear it move.
Thunder is modelled on the physics
Thunder is the part most ambient apps get wrong, because a filtered noise burst sounds like a filtered noise burst. Three things separate real thunder from that, and all three are modelled here.
Sound is slow. Light is effectively instant; sound covers about 343 metres per second. Each strike is placed at a real distance and its audio is delayed by the true travel time, so a flash three kilometres out is followed by roughly nine seconds of silence before you hear anything.
Air eats high frequencies. It absorbs them far faster than low ones, so distance decides character rather than just volume. A close strike is a bright, violent crack; a distant one has had its entire top end stripped away and arrives as pure low rumble. Distance drives the filter cutoff, not only the gain.
Thunder is never one impact. A lightning channel is kilometres long, so sound from its near end reaches you well before sound from its far end. That spread is what produces the roll, and it is why the peal is assembled from a series of overlapping swells at irregular intervals rather than from a single decay curve. It is also why distant thunder rumbles for so much longer than close thunder does.
The result is that “close” and “distant” do not sound like the same event at two volumes. They sound like different events, which is what they are.
The rain costs the CPU nothing
A rain field of tens of thousands of drops is the obvious place for a browser to fall over, because the naive approach updates every particle’s position on the CPU every frame and uploads the result to the GPU.
Cloudfall does no per-frame particle work at all. Each drop’s position is a closed-form function of time and a per-drop seed, evaluated in the vertex shader — so the entire field is one draw call with nothing to update, and the cost of adding drops is the GPU’s alone. Wind is a uniform, so a shifting gust leans the whole field without touching a single vertex on the CPU.
Drops are drawn as elongated, slightly skewed shapes rather than spheres, because that is what a falling drop looks like to a camera with a real exposure time, and they refract what is behind them rather than being tinted blue. Rain is not blue. It is a lens.
The ocean is a sum of waves
The water is a Gerstner (trochoidal) wave surface: several waves of different wavelength, direction and steepness summed together. The defining property of a Gerstner wave is that vertices move horizontally as well as vertically, which is what lets crests sharpen and peak instead of staying rounded like a plain sine surface. Real swell has pointed crests and broad troughs, and that asymmetry is most of what makes water read as water.
Because the wave function is shared rather than baked, spray can be emitted exactly where the crests are without ever reading pixels back from the GPU — the particles evaluate the same function the surface does and find the peaks themselves.
Surf is handled separately. Continuous filtered noise reads as a hiss rather than a sea, so individual breaking waves are modelled as discrete events with the asymmetry real ones have: roughly a fifth of their life rearing up, the rest draining away. Getting that ratio backwards is the classic tell of synthetic surf.
What the visuals can and cannot hear
When the audio is reachable, it is analysed with a real FFT and the scene responds to the actual signal — the storm we generate ourselves, a local file you load, or any tab whose audio you share with the page.
SoundCloud is the exception, and it is worth being plain about it. It plays inside a cross-origin iframe, and browsers do not permit a page to read audio from one. No amount of engineering changes that; it is a security boundary, and it is the correct one. In that mode the motion is synthesized from an envelope and the interface says so in as many words rather than implying a measurement that is not happening.
If you want the real thing with music from anywhere — Spotify, Apple Music, YouTube — play it in another tab and use the tab-sharing option in the music panel. That path hands the page an actual signal, and the visuals follow it exactly.
Grading and framing
The scene is rendered to a target and then put through a bright pass, a separable blur at quarter resolution, and a composite that applies a baked 32×32×32 colour lookup table, a vignette, film grain and a touch of chromatic aberration. The LUT is generated at build time from a small set of colour stops rather than shipped as an image, so the grade lives in code and can be reasoned about.
Cinematic mode records the canvas and the audio together, at a chosen aspect ratio — the renderer is resized to the exact output resolution and the canvas is letterboxed on screen, so what you compose is what gets exported. The watermark is drawn inside the 3D scene rather than as an overlay, because a DOM overlay is never part of a canvas capture.
Try it
Each of these opens the same engine in a different state: drizzle, steady, rolling thunder, squall, tempest, downpour, still water, night swell.
Or start from the default and move the sliders yourself. It is free, there is no account, and nothing you load leaves your device.