Smoke Simulation
A grid-based smoke simulation in C++ that solves the incompressible Navier–Stokes equations on a Eulerian grid — semi-Lagrangian advection, a Gauss–Seidel pressure projection, and vorticity confinement to keep the swirl alive.
╌╌╌╌
A physics-based smoke simulation in C++. The fluid lives on a fixed 2D Eulerian grid (the solver runs on a lattice of cells) with velocity, pressure, vorticity, and smoke density stored per grid node, advanced by the Navier–Stokes equations and rendered as drifting smoke.
Smoke behaves as an incompressible fluid, so its velocity field obeys momentum balance under pressure, viscosity, and external forces, together with a divergence-free constraint:
Each timestep runs the same four-step sequence: inject smoke and velocity at the sources, advect the fields, apply vorticity confinement, and project the velocity back to a divergence-free state.
- 1state: velocity , pressure , smoke density on the grid
- 2inject sources: add inflow velocity and density at the emitters
- 3advect through itself (semi-Lagrangian, RK2 backtrace)
- 4advect through
- 5(vorticity confinement, )
- 6solve by Gauss-Seidel, 40 sweeps
- 7(project back to divergence-free)
A handful of inflow emitters seed the motion: grid nodes within a small radius of an emitter take its velocity, with radial, tangential, and mixed emitters set around the domain. The fields then move by semi-Lagrangian advection, which updates a node by tracing the velocity field backward (a midpoint half-step, then a full step) and bilinearly interpolating the old field at the departure point. Tracing backward and interpolating this way is unconditionally stable, which is what lets the smoke take large steps without blowing up.
Advection leaves the velocity field with nonzero divergence, so a projection step restores . The solver takes the divergence by central differences, solves the Poisson equation with forty Gauss–Seidel sweeps, and subtracts the pressure gradient from the velocity.
Discretizing the fluid numerically damps small-scale rotation, so the smoke loses its curl and goes limp. Vorticity confinement measures the local vorticity , builds unit vectors pointing up the gradient of toward its concentrations, and adds the force — with confinement strength in the code — back into the velocity, restoring the swirling detail that makes rising smoke read as smoke.
References
╌╌ END ╌╌