If you're new to the series or would like to catch up on the fundamentals, you can find every previous lesson, along with a summary of what each tutorial covers, here:
GLSL Beginner Series: A Journey from Your First Shader to Procedural Animation
In the previous tutorial, we explored Perlin Noise and learned why it became one of the most influential procedural algorithms in computer graphics. A single layer of Perlin Noise already creates smooth and natural looking patterns.
Today we'll discover how artists make those patterns much richer by combining multiple layers of noise.
Fractal Brownian Motion in GLSL: Building Rich Procedural Noise
Look at a mountain from far away.
You can see its overall shape.
Walk closer and you'll notice smaller hills.
Closer still, you begin to see rocks.
Even closer, tiny cracks appear.
Nature is full of detail at many different scales.
One layer of noise usually isn't enough to recreate this complexity.
Instead, we stack several layers together.
This technique is called Fractal Brownian Motion, often shortened to FBM.
FBM simply means adding several copies of the same noise.
Each layer is slightly different.
Some layers create large shapes.
Others create medium details.
The smallest layers add fine texture.
When combined, they produce patterns that look much more natural than a single layer of noise.
We begin with one noise sample.
float value = noise(vUv);
This creates the large features.
Think of it as the outline of a mountain or the shape of a cloud.
Now add a second sample.
value += noise(vUv * 2.0) * 0.5;
Notice two things.
The coordinates are multiplied by 2.0.
The result is multiplied by 0.5.
The first change creates smaller details.
The second prevents those details from overpowering the larger shapes.
Continue repeating the process.
value += noise(vUv * 4.0) * 0.25;
value += noise(vUv * 8.0) * 0.125;
Each layer becomes smaller.
Each layer also contributes less to the final image.
This gradual reduction creates a balanced result.
The coordinate multiplier controls the frequency.
Low frequency produces large smooth shapes.
High frequency creates tiny details.
Increasing the frequency means zooming into the noise.
noise(vUv * 16.0)
This produces very fine texture.
The multiplier after the noise controls the amplitude.
* 0.5
or
* 0.25
This controls how much each layer contributes.
Large details remain dominant while smaller details gently decorate the surface.
Instead of writing every layer manually, most shaders use a loop.
float fbm(vec2 uv){
float value = 0.0;
float amplitude = 0.5;
for(int i = 0; i < 5; i++){
value += noise(uv) * amplitude;
uv *= 2.0;
amplitude *= 0.5;
}
return value;
}
This creates five layers automatically.
The result looks far more natural than a single noise sample.
Using the function is simple.
float n = fbm(vUv * 3.0);
gl_FragColor = vec4(vec3(n),1.0);
Instead of smooth blobs, you'll begin to see textures that resemble nature.
FBM becomes much more interesting with color.
vec3 color = mix(
vec3(0.05,0.15,0.35),
vec3(0.85,0.9,1.0),
n
);
The result begins to resemble clouds drifting across the sky.
Different color gradients can completely change the mood.
Move through the noise field.
vec2 uv = vUv;
uv.x += uTime * 0.05;
Now every layer moves together.
The animation feels soft and organic.
Perfect for clouds, smoke, or magical energy.
Try using only two layers.
The pattern looks simple.
Use six or seven layers.
The details become much richer.
More layers create more realism, but they also require more calculations.
Finding a balance is important in real time graphics.
FBM appears in many procedural effects.
Many procedural shaders begin with nothing more than FBM.
Use three layers.
Use six layers.
Change the frequency.
Change the amplitude.
Animate the coordinates.
Try different color gradients.
Observe how each layer adds another level of detail.
Can you create these effects?
Each effect begins with the same FBM technique.