
In the current model, fire always rises upwards at the same speed, it never moves sideways or stops, and there are no swirls or turbulence. Uneven cooling improves the look of the fire dramatically, implementing it will make the fire simulation look something like this: Varying the rate at which the cooling texture scrolls affects the look of the flames, a slower scroll speed gives a more billowing look, and a faster scroll speed makes the fire look more turbulent.Īs far as I know, the first description of using a cooling texture instead of constant cooling was by Hugo Elias. The cooling grid/texture should tile and scroll upwards at approximately twice the speed of the heat grid. This particular texture was generated in processing.js by drawing circles of random sizes and intensities and blurring the image repeatedly. You want the cooling texture to be fairly smooth and to contain a mix of large blobs and high frequency noise. Instead of simply using a constant cooling factor, we use a cooling map, a grid of pixels of the same size as our heat grid. The easiest way to dramatically improve the look of the fire is to introduce uneven cooling. Also the shape of the “flames” is very blobby and soft. It sort of looks like fire, but the movement is strictly vertical, it doesn’t really move in the billowing, fluid-like way real fire does. Implementing this will give you something that looks a bit like this: By translating the noise texture a random amount every flame, we get randomly flickering burning fuel. To inject heat where fuel is burning we render the burning parts to the heat texture with additive blending, modulated with a high frequency noise texture to simulate flicker. This is easy to translate into WebGL, we store the heat in a texture, and use a pixel shader to blur and convect the heat. Pixel(x, y - 1) = (sum / 4) - cooling_amount In pseudocode: sum = pixel(x+1, y) + pixel(x-1, y) + pixel(x, y+1) + pixel(x, y-1) It is simple to combine the blurring and convection into a single step. Then we repeat the process, injecting heat, blurring and convecting and so on. To render the fire, we map pixel intensities in the heat texture to a color ramp that goes from black, via red and orange to white, simulating black body radiation. Convection is simulated by scrolling the grid upwards, and cooling by simply subtracting a constant from each pixel. This simulates heat spreading to neighboring grid points. To simulate diffusion, the grid of pixels is blurred. To get the fire started we plot heat (i.e pixels with maximum intensity) at the locations in the grid which have burning fuel. The basic idea is to start with a grid of pixels, each pixel representing heat at that location. The very simple model of fire used for the effect contains four parts: a heat source (generally something that is burning, i.e the top of a torch), convection (the fact that hot stuff tends to rise and cool stuff tends to sink), diffusion (heat will gradually spread out), and cooling. It seems like there should be tons of indie 2D games with awesome fire effects, flamethrowers, burning zombies, torches or whatever, but since I haven’t found any, here’s my attempt to document how you make a simple and awesome fire simulation. It doesn’t translate very well to three dimensions (since all you get is a flat texture), but it works great for 2D games. If you’re on a phone or tablet, you can rotate your device and see howĮven though the effect is easy to implement, fairly cheap to simulate and looks really good, I rarely see it in games. Try touching the fire, or clicking and dragging with your mouse. That doesn’t look much like real fire, but with some simple tweaks you can get something that looks good, runs on most graphics hardware and is easy to implement: The way the algorithm works seems to introduce a fair amount of diffusion already so I figured I'd just drop that term.Back in the early nineties, the demoscene was in love with a simple fire effect, that generally looked something like this:įire demo by Iguana - screenshot by If you are wondering why I left out diffusion in this demo. All the other logic is in the shader files. The flow is defined inside the main.js file. Here is an overview of the data flowing between the shaders.
#Webgl fluid simulation code#
Most of the interesting code for this demo lives in shaders. View WebGL fluid simulation demo Code Overview It's nicely illustrating how muchįaster the GPU accelerated WebGL version is compared to the canvas one.Īs an added benefit, it does not explode anymore because the boundary conditions are now properly enforced. It's doing roughly the same thing as the canvas one. A little while ago I released a canvas based fluid simulation demo.
