How to animate fire that "looks" good. More emphasis is placed on making the fire look realistic and being able to procedurally control the fire. Less emphasis is placed on the actual physics model.
I read the paper Structural Modeling of Flames for a Production Environment by Arnauld Lamorlette and Nick Foster, 2002 ACM. This paper outlines an essential model to create fire animations. This essential model is shown in the figure below. For some background references I skimmed some of the papers in the References section. For example, the paper Modeling the Motion of a Hot, Turbulent Gas by Nick Foster and Dimitris Metaxas gives some background information for understanding the "wind field" that affects how a flame moves.
For implementation purposes, I read Chapter 16 in the Numerical Recipes in C: The Art of Scientific Computing which describes Runge-Kutta methods for solving ordinary differential equations.
I did all my work in C++/OpenGL/FLTK. I used a plug-in to get the flame into Maya. The following is a description of what I did for each step of the algorithm above.
Step 1: Flame Spine
For this step I searched long and hard online for B-spline code that can interpolate through points. I found some code from Columbia University, written by Sameer A. Nene, Shree K. Nayar, and Hiroshi Murase (1994). This code uses nonuniform rational B-splines with knots. It uses vectors of N-dimensions. I extracted what I needed from this code and added functions for basic vector operations. A B-spline curve representing the flame spine is shown in the figure below. The yellow points indicate the control points of the spline.
Step 2: Wind Field
There are four components of the wind field as given in the paper. These four components are the following:
For this step, I implemented the first three components on this list.
To model thermal bouyancy, each particle in the flame (particles are obtained in the next few steps) was given an age and a temperature. The bouyancy motion was strictly in the positive y (opposite gravity) direction. The particle velocity was dependent on its temperature and age. Particles higher up in the flame have a higher temperature, causing them to move more quickly.
To model diffusion, I did a background search on Brownian motion and found that it is a partial differential equation and depends on a Gaussian distribution for random motion. I was not sure how exactly to represent this in my ordinary differential equation without using a separate PDE solver. So instead I chose to have each particle make a random move in 3-D space. The random move step size is determined by a Gaussian distribution with a standard deviation given as a parameter. A larger step size would give a flame that looks like it is being moved about more forcefully.
To model the motion due to movement of the source simply involved putting the x, y and z velocities of the flame source into the ordinary differential equation. This is useful, for example, when animating a person holding a candle while walking. The walking motion causes some wind and the whole flame moves.
The wind field differential equation was solved using rk4 as implemented in the Numerical Recipes in C. This determined the flame's position at any given time.
Step 3: Flickering / Separation
This step involves modeling flame flickering and separation. This step is dependent on the overall height of the flame at any given time. The heights in this step are input as parameters. At a given height, with a certain probability part of the flame can separate and dissipate over time, or the flame can flicker. Flickering simply means that the flame is erased and restarts as a point on the source. I only modeled flickering for this step.
Step 4: Profile
A profile of the flame shape is used to create a 3D model of the flame. This profile can be obtained in many ways and even hand-drawn. I obtained a flame profile by finding an image of a flame on the internet, then thresholding the image to black and white. (This was useful because the same image can be used to get a profile and to get the appropriate color samples for any particle defined within the profile.) Using the thresholded image, the profile was determined by the positions of the first white points in each row. These points were then used to create a B-spline, which was revolved around an axis to obtain a 3D shape. One such flame with its thresholded image is shown below.
![]() |
![]() |
To obtain particles that represent the flame, I randomly sampled 3D points within a cube enclosing the flame shape. To determine if a sample was within the flame's parametric profile, I simply used the y-coordinate of the sample to obtain the flame's radius at that level. If the sample was in the circle defined by this radius, it was stored as a particle.
Step 5: Noise
I did not include this step in the final implementation because the results did not look good.
Step 6: Transform
This step is used to transform the flame created by a profile to the flame spine which moves in the wind field. I implemented this step using quaternions to rotate each particle about an axis defined by its position before and after transformation.
Step 7: Render
For this step I only mapped colors from the original image to each particle in the flame. Ideally, the rendering would also involve the camera position as this is how the paper suggests.
Two result images are shown below.
It was very difficult to integrate this into the Maya movie because of plug-in issues. The plug-in was unstable and would crash if the wrong button in Maya was pressed. In addition, batch rendering did not work with the plug-in, so any part of the movie using this flame would have to be rendered frame-by-frame by hand. Given these issues, we thought the best place to use the flame would be in the credits.
The steps involved are not completely exclusive to themselves. Basically, steps 1-3 could be one exclusive unit. Steps 4 and 5 could be another exclusive unit. Then any step from step 6 and beyond combines these two units. I would advise doing the basics then adding extra and more complicated stuff after the basics are done.
The following image is an example created in Maya. The flame was created from my code.
The following is an example movie of the results. They are all the same movie, but using different compression in case you can't open one on your computer.
Fire (DivX 5.0 Codec)
Fire (Microsoft MPEG-4 Video Codec V1)
Fire (Microsoft MPEG-4 Video Codec V2)
Fire (Microsoft Video 1 Compressor)
The final video of the flame in Maya turned out pretty good and I am happy with the results. Although I was unable to keep the same color mapping from the images, Maya had some useful material features to create incandescence and glow for the fire particles.
These are the slides from the presentation I gave on this project:
05/10/2003