Stable Fluids: Why Smoke Simulators Never Blow Up
August 27, 2026 · DevTools
Before 1999, real-time fluid simulation was a grenade: every explicit scheme eventually blew up, sending velocities to infinity and dye to noise. Then Jos Stam published "Stable Fluids" and the pin came out of that grenade permanently. Nearly every smoke-and-ink effect you've seen in games and demos since — including the one in a browser tab near you — is his recipe: advection that cannot explode, a pressure step that enforces water's incompressibility, and a small bandage for the honesty the first two cost.
The trick: look backwards, not forwards
Navier-Stokes says fluid velocity gets carried along by itself — advection. The naive approach moves quantity forward with the flow and lands between grid cells, requiring interpolation that injects energy and detonates the sim. Stam's inversion: for each cell, ask where did this fluid come from? Trace the velocity backwards one timestep, bilinearly sample whatever was there, and declare that the new value. Since sampling never extrapolates beyond the data, it can only ever produce values between existing ones. Unconditionally stable, at any timestep, on any grid. The price is diffusion — backward tracing smears sharp features, which is why undyed smoke looks soft and why our third ingredient exists.
The pressure step: making water honest
Real fluids are incompressible: whatever flows into a region must flow out. Pure advection doesn't respect that — velocity fields converge into sinks like water into a drain that isn't there. The fix is a projection: solve a Poisson equation for a scalar pressure field whose gradient, subtracted from velocity, makes the divergence vanish. Incompressibility becomes a constraint applied every frame, and that constraint is why fluid pushes sideways around obstacles instead of conveniently stopping. The Jacobi iterations (16 in this tool's solver) are the relaxation method for that solve; more iterations mean harder incompressibility at linear cost.
The bandage: vorticity confinement
Backward advection's smearing has a signature: small eddies die first. Vorticity confinement measures the local curl (rotation) of the velocity field, finds where numerical diffusion is eating it (the curl gradient), and re-injects a rotational force along that gradient. It's a cheat in the best sense — physics-inspired energy restoration targeted exactly at what the numerics destroyed. Slide it to zero and watch smoke go laminar; max it and watch every wobble amplify into turbulence. One scalar, whole personality.
The Lagrangian other half
Eulerian grids are one worldview: properties at fixed points, fluid flowing past. The other half — particles carrying their own state — powers the N-body side of the sandbox. Verlet integration stores only current and previous positions (velocity implied by their difference), which makes constraints trivially stable: walls, springs, elastic collisions all become position corrections. That's the scheme behind cloth, rope and ragdoll physics in every game engine. The two halves even compose: grid-based fluid pushing Lagrangian particles is how spray and foam layer onto liquid sims in film.
Feel it, then ship it
The reason this particular tool chain matters: fluid intuition is un-buildable from equations alone. You need to drag a vortex and watch it pair-split, crank confinement and see turbulence ignite, watch a pressure solve route flow around a wall you just drew. And when the feel is right, the export path turns play into product — the same constants, the same step order, as code that runs anywhere. Stam gave us stability; the browser gives us the laboratory.