A fluid solver hands you one thing: a velocity field — at every cell of a grid, an
arrow saying which way the air is moving and how fast. That is the machinery behind a
The trick is to ride passengers on the flow. Smoke is a cloud of little particles too light to matter to the air but heavy enough to catch the light; we model that cloud as a density field that the velocity simply carries along. Fire adds heat — a temperature field, a reaction that turns fuel into hot expanding exhaust, and a colour that glows from deep red to white as it burns. Get three forces right — advection, buoyancy, and a swirl-preserving nudge called vorticity confinement — and dead grid data starts to roll like the real thing.
Think of smoke as a dye poured into the air. The dye does not push the air around (it is
passive); it just goes where the air already goes. We store its concentration as a scalar
field
Advection alone gives you smoke that drifts, but not smoke that lives. A puff released into a still velocity field just sits there and slowly blurs. Two ingredients are missing: the reason smoke goes up, and the reason it curls.
Hot smoke is less dense than the cool air around it, so it floats up — the same reason a hot-air balloon climbs. In the simulation we add an upward buoyancy force to the velocity field wherever the fluid is hot or the smoke is light:
Read the two terms:
Here is the anatomy of a plume. A hot source at the bottom feeds smoke upward under buoyancy (the vertical arrows). But as fast-moving smoke shears past slower surrounding air, the flow rolls up into a vortex — a spinning eddy — and it is those rolls, tumbling over one another, that give real smoke its restless, braided look. Reveal the steps to build the plume up.
The whole believability of the shot hinges on protecting that curl. And that is precisely what a plain grid solver quietly destroys.
Every step, semi-Lagrangian advection interpolates between grid cells — and interpolation averages, which smooths. Averaging bleeds energy out of the smallest swirls first, so after a few frames the fine, high-frequency vortices are gone and you are left with a bland, over-smoothed blob. This is numerical dissipation: the grid acting like an unwanted viscosity, thick as syrup, damping out exactly the detail that makes smoke interesting.
Fedkiw, Stam and Jensen's answer (SIGGRAPH 2001) is vorticity confinement: measure
where the swirl is being lost and inject a force that spins it back up. First compute the
Because it only reinforces swirls that are already there, confinement restores the look of turbulence without you having to resolve every tiny eddy on the grid — a cheap fix that made low-resolution smoke suddenly filmable.
Release a warm puff into a coarse
Version A — advection only. With no buoyancy the puff never rises; with no confinement, every step's interpolation averages neighbouring cells and dissipation eats the small vortices within a dozen frames. The result is a grey ball that expands and fades in place — the dreaded "cotton-wool" smoke. It is technically a fluid; it looks like a cloud of nothing.
Version B — add buoyancy. Now the warm puff climbs. As the rising core shears past still air, a vortex ring tries to form at the edges — good — but dissipation is still shaving those rolls flat almost as fast as they appear. You get a rising blob with a hint of a mushroom, still soft and lifeless around the edges.
Version C — add vorticity confinement. The confinement force feeds energy straight back into the nascent vortex ring, so the rolls survive, tighten, and cascade into finer curls. The same coarse grid now produces the characteristic curling, braided plume — smoke that tumbles over itself the whole way up. Nothing changed but one extra force term countering the grid's own numerical viscosity.
The lesson: buoyancy tells the smoke where to go; vorticity confinement is what keeps it alive on the way there.
Fire is smoke's hotter sibling. Everything above still holds, plus three additions.
A temperature field. Fire carries a scalar
A reaction. A fuel field ignites above a threshold temperature and burns: fuel converts to hot exhaust, releasing heat and expanding (the flow gains volume at the flame front, which is what makes explosions push outward). As the burn finishes, unburned carbon lingers as soot — that is the smoke that trails a cooling fire.
Blackbody colour. Hot matter glows, and the colour it emits depends only on its temperature — the blackbody spectrum. We map temperature straight to emitted colour:
Coolest flame edges glow deep red; the hottest core burns white-hot; and once temperature drops below the visible-glow threshold, the fuel is spent and you see only dark soot smoke. Because the colour is emitted (the fire makes its own light) it is rendered as an emissive volume, while the smoke above it is rendered by how it absorbs and scatters light passing through.
Zoom out and the whole thing is two stages. Simulate: advance the velocity, density and temperature fields on a grid each frame (advect, add buoyancy + confinement, project to keep the flow incompressible, react and cool). Render: march rays through the resulting volume, accumulating emission from hot cells (the fire's glow) and absorption/scattering from dense cells (the smoke), to produce the final image. Grid in, glowing image out.
Which half you can afford depends on your budget. Film actually runs the simulation — big grids, hours per frame, physically-grounded so it holds up in close-up and slow motion. Games almost never can: at 60 frames a second there is no time to solve a fluid, so they fake it — animated sprite sheets, scrolling procedural noise, a handful of GPU particles, and cheap tricks that read as smoke from a distance without solving a single equation. Same goal, opposite ends of the cost–fidelity trade.
A candle flame is that pointed teardrop entirely because of buoyancy. On Earth, hot combustion gases are lighter than the surrounding air, so they rush upward, stretching the flame into a rising tongue and pulling fresh oxygen in at the base. Take gravity away — light a candle on the Space Station — and there is no "up" for the hot gas to rise into. Buoyancy vanishes, the flame stops being drawn into a point, and it settles into a small, dim, blue sphere, fed only by slow diffusion of oxygen from every side. It is a lovely reminder that the shape of fire is not intrinsic to burning at all — it is the buoyancy term in disguise, which is exactly why a simulator that gets buoyancy right gets the silhouette of fire right.
The single most common way CG smoke goes wrong: it comes out soft, puffy and lifeless — "cotton-wool" smoke that expands and fades without ever rolling. The culprit is almost never your buoyancy or your colours; it is numerical dissipation. Every semi-Lagrangian advection step interpolates between cells, interpolation averages, and averaging smooths away the small-scale vortices that are the turbulent detail. The grid is acting like an invisible, unwanted viscosity.
The fixes all target that loss directly: turn on vorticity confinement to spin the swirls back up; raise the grid resolution so finer vortices survive; or add wavelet / procedural turbulence to synthesize high-frequency detail on top of the coarse solve. What you must not do is reach for more buoyancy or a fancier colour ramp — neither touches the missing curl, and you will just get a taller, prettier blob. Diagnose "no roll" as a dissipation problem, every time.
Cheerfully, yes. That roaring torch in your favourite game is very likely a looping
sprite-sheet flipbook drawn by an artist, or a shader scrolling