Using the particle system described in here we will design a framework to create a nice looking real-time smoke effect. The keyword here is effect, to create physically accurate smoke we would have to go into fluid dynamics and solve some pretty complex differential equations which are not particularly stable.
However, we don't want to achieve physically accurate smoke, we just want to get a nice looking smoke effect to add to a virtual world to add a little bit of realism. The first step in any project using a particle engine is to decide how to render the particles. To create effects such as rain, fire, smoke or sparks, the most common choice is to use textured sprites, rendered either as point sprites or as camera aligned billboards.
The textured sprites are usually alpha blended into the scene, to make it difficult to distinguish one particle from another (they tend to merge into a big blob). To design our smoke particle texture we will use Perlin noise. I will not go into any details as to how Perlin noise works or how to implement it, but Perlin noise is a method to generates continuous pseudo random numbers, and the 2D equivalent looks fairly similar as the noise generated in the height-map generation tutorial. Most tools (such as the Gimp and Photoshop) have already a Perlin filter built in, I will be using the Gimp.
Now we will generate the alpha channel for this smoke particle. We start by erasing the whole alpha channel (as to make the whole image transparent) and then placing a centered circle with full opacity. Then apply some Gaussian blurring to the image, vary the magnitude until you reach something like the following:
After aplying this alpha channel to the perlin noise you get your final smoke particle, which should look something like this:
Now that we have our smoke particle, we just need to decide how will the particle system behave. Let us observe that real smoke tends to go up (unless affected by wind), and as it goes up it tends to dissipate into the air and disappear (visually at least). So our smoke particles will have one additional property we shall call life.
When a smoke particle is created we will assigned it a time to live (life) from a uniform random distribution between 0 and MaxLife (tweek this value to achieve different kinds of smoke). At each time-step in addition to solve the differential equations of the particle system we will also decrease the time to live for each particle.
When a particle reaches a time to live of 0, we will destroy this particle and create a new one. All new particles are created in the smoke source, that in this example will be described by a square. Every newly created particle is again assigned a position using a random distribution in the range [-1,1] for the x and z axis.
For efficiency, instead of creating and destroying particles, every time a particle reaches a time to live of 0, we will reinitialize its position and reset its velocity and force. The only force acting on the particle system will be a constant force acting upwards (something like an inverted gravity vector) and optionally some wind. To make the smoke particles gradually disappear multiply their alpha channel by ttl/MaxLife, where ttl is a variable holding their remaining life.
The following image shows an example of this smoke effect in action, this particular example shows a chimney (I know the model is quite poor, is just for illustration purposes) and some smoke coming out of it. This effect was achieved using only 80 particles and the chimney was modelled using four textured quads. The force vector used was <0,0.005,0>.
Click the following image to see the particle system in action.