Fire is constantly changing.
The flames stretch upward.
They flicker from side to side.
They become thinner near the top.
Every moment looks different, yet the movement feels smooth and natural.
Although it seems complicated, procedural fire can be created using the same techniques we've been learning throughout this series.
A convincing flame usually has four ingredients.
A vertical shape.
Animated noise.
Natural distortion.
A warm color gradient.
None of these require image textures.
Everything can be generated mathematically.
We'll begin with the familiar UV coordinates.
vec2 uv = vUv;
The bottom of the screen will become the base of our flame.
Instead of moving sideways, fire rises upward.
Move the noise downward.
uv.y -=
uTime * 0.5;
Although the coordinates move downward, the flame appears to rise upward.
This happens because we're sampling different parts of the noise field over time.
Generate a smooth noise pattern.
float n =
fbm(
uv * 4.0
);
The noise becomes the foundation of the flame.
Real flames never rise in perfectly straight lines.
Use the noise to bend the coordinates.
uv.x +=
n * 0.2;
Now the flame begins to flicker naturally.
Fire becomes narrower toward the top.
We can simulate that mathematically.
float flame =
1.0 -
length(
vec2(
uv.x,
uv.y * 1.5
)
);
This creates a tall teardrop shape.
Multiply everything together.
flame *= n;
The smooth flame now gains irregular movement.
Instead of a simple gradient, it starts to resemble real fire.
#ifdef GL_ES
precision mediump float;
#endif
uniform float uTime;
varying vec2 vUv;
void main(){
vec2 uv = vUv;
uv.y -= uTime * 0.5;
float n = fbm(uv * 4.0);
uv.x += n * 0.2;
float flame =
1.0 -
length(
vec2(
uv.x,
uv.y * 1.5
)
);
flame *= n;
flame = clamp(flame,0.0,1.0);
gl_FragColor = vec4(vec3(flame),1.0);
}
Even without colors, the movement already resembles a flickering flame.
Now create a warm gradient.
vec3 color = mix(
vec3(0.8,0.0,0.0),
vec3(1.0,0.9,0.2),
flame
);
Dark red forms the cooler areas.
Bright yellow creates the hottest parts.
The shader suddenly begins to look like real fire.
Increase the noise frequency.
fbm(
uv * 6.0
);
The flame develops finer details.
Decrease the frequency.
The flame becomes slower and softer.
Increase the movement.
uTime * 1.0
The fire becomes energetic.
Reduce the value.
The flame burns more gently.
Duplicate the coordinates.
Offset them slightly.
Draw several flames together.
This creates a campfire or torch effect.
Many professional fire shaders are simply several procedural flames layered together.
Fire shaders appear everywhere.
Everything begins with noise and coordinate distortion.
Make the flame taller.
Make it shorter.
Increase the distortion.
Slow the animation.
Create blue fire.
Create green magical fire.
Layer several flames together.
Observe how each adjustment changes the final appearance.
Can you create these effects?
Each one uses exactly the same procedural techniques.
Today we built our first animated procedural material.
By combining FBM, coordinate distortion, animation, and color gradients, we created a convincing fire effect entirely from mathematics.
This demonstrates how procedural shaders can generate complex animations without relying on image textures.