Rendering smoke and fire in real-timeA student project for the Advanced Image Synthesis course 2006
Ingemar Rask and Johannes Schmid
Initial project description
As a project for the Physically-based simulation class, Johannes Schmid implemented a 3D Navier-Stokes fluid solver based on Jos Stam's "Stable fluid"  method and publically available source code thereof . A good computational model of fire using fluid simulation was presented by Nguyen et al. . However, their model seemed to involved to implement for this miniproject, so we just took some ideas from it.
What we percieve as yellow-reddish flames in a fire is the blackbody radiation of hot gaseous products, which are the result of combustion. For this project, we limited ourselves to the simulation of this part of the fire and ignored the actual combustion process. The fluid solver is used to simulate the density and temperature field in the fire. We simulate only one scalar field and use it for both temperature and density (conceptually), which is of course a simplification. Both fluid and fluid velocity are seeded randomly at the bottom of the simulation domain. The temperature field is added to the upward velocity field to simulate buoyancy. Vorticity confinement, as described in , is applied to add further turbulences. The simulation is done in a grid of 32x32x32 voxels, which performs at over 5 fps on fast machines.
The rendering is obtained by drawing alpha-blended viewplane-aligned slices of the simulation domain, which is represented by a 3D texture. To obtain correct interpolation within the grid, the 3D texture contains the temperature values instead of actual color values. A fragment program then uses the interpolated temperature value to look up the color from a second texture. This color texture is obtained by integrating the Planck Spectrum and taking into account the adaption of the eye, as described by Ngyuen et al.  in Section 5.2.
For rendering of smoke, it is crucuial to have some form of illumination. We used CPU-based ray casting to assign an illumination value to each voxel. As the light ray advances through the volume, the local density value is used to attenuate the brightness of the ray. The illumination value then determines the color of the pixel, and the density value determines the transparency. Since a direct interpolation of color and alpha value will give the correct result in this setting, no fragment program is needed for smoke rendering.
Screenshots and VideosA few shots of the fire:
Video (MPEG2, 2 MiB)
Drawing only 10 slices and displaying their outlines:
Video (MPEG2, 4 MiB)
All the programmming has been done in C++ under Linux. We used SDL  to perform various system-level tasks, such as setting up the output window and multi-threading. The rendering itself is done in OpenGL, which is supported by SDL.
Since both SDL and OpenGL are availible on various platforms, the code should be fairly simple to port. Unfortunately, Windows only supports OpenGL 1.0 at the moment, whereas 3D textures were introduced in OpenGL 1.2. It would be possible to make use of 3D textures through extensions (EXT_texture3D).
Command line: ./fluid [-w|-l <filename>]