Look at the sky on a clear day.
Clouds rarely have sharp edges.
They slowly grow, merge together, drift across the horizon, and disappear.
If you look closely, you'll notice large cloud formations filled with smaller details.
This layered appearance makes clouds a perfect use case for procedural noise.
What Makes Clouds Look Natural?
Most cloud shaders use four simple ideas.
Layered noise.
Soft edges.
Slow animation.

A smooth color gradient.
We've already learned every one of these techniques.
Now we'll combine them into a complete material.
Starting with the UV Coordinates
Begin with the screen coordinates.
vec2 uv = vUv;
These coordinates represent our sky.
Making the Clouds Move
Clouds drift slowly with the wind.
Move the coordinates horizontally.
uv.x +=
uTime * 0.03;
The movement is intentionally subtle.
Fast movement makes clouds look unnatural.
Creating the Base Shape
Generate layered FBM.
float cloud =
fbm(
uv * 3.0
);
The large soft blobs already resemble distant clouds.
Adding More Detail
Clouds contain both large and small features.
Increase the number of layers inside the FBM function or increase its frequency.
float detail =
fbm(
uv * 6.0
);
Mix the detail into the base pattern.
cloud +=
detail * 0.3;
The clouds become richer without becoming noisy.
Softening the Edges
Real clouds fade gradually.
Use smoothstep().
cloud =
smoothstep(
0.4,
0.7,
cloud
);
The harsh edges disappear.
The result becomes soft and fluffy.
Creating the Sky
Choose two shades of blue.
vec3 sky = mix(
vec3(0.25,0.45,0.85),
vec3(0.75,0.90,1.0),
vUv.y
);
The horizon becomes darker while the upper sky appears brighter.
Drawing the Clouds
Blend white into the sky.
vec3 color =
mix(
sky,
vec3(1.0),
cloud
);
The clouds now appear naturally against the background.
Complete Shader
#ifdef GL_ES
precision mediump float;
#endif
uniform float uTime;
varying vec2 vUv;
void main(){
vec2 uv = vUv;
uv.x += uTime * 0.03;
float cloud = fbm(uv * 3.0);
cloud += fbm(uv * 6.0) * 0.3;
cloud = smoothstep(0.4,0.7,cloud);
vec3 sky = mix(
vec3(0.25,0.45,0.85),
vec3(0.75,0.90,1.0),
vUv.y
);
vec3 color = mix(
sky,
vec3(1.0),
cloud
);
gl_FragColor = vec4(color,1.0);
}
Even with relatively little code, the shader already resembles a bright daytime sky.
Creating Storm Clouds
Reduce the sky brightness.
vec3(0.15,0.20,0.35)
Replace the white clouds with gray.
vec3(0.75)
The atmosphere immediately feels heavier.
Creating Sunset Clouds
Replace the cloud color.
vec3(
1.0,
0.75,
0.55
);
The clouds now appear warm as though illuminated by the setting sun.
Making the Clouds Move Faster
Increase the animation speed.
uTime * 0.08
For peaceful skies, smaller values usually look more convincing.
Where Are Procedural Clouds Used?
Cloud shaders appear in countless projects.
Open world games.
Animated skies.
Weather systems.
Flight simulators.
Motion graphics.
Fantasy environments.
Space scenes.
Background animations.
User interfaces.
Digital artwork.
Most of them begin with layered FBM.
Try These Experiments
Create a clear sky.
Create storm clouds.
Create sunset clouds.
Increase the cloud detail.
Slow the animation.
Speed it up.
Add a second cloud layer moving in another direction.
Observe how these small changes create completely different weather conditions.
A Small Challenge
Can you create these skies?
A bright summer afternoon.
Heavy rain clouds.
A colorful sunset.
A magical fantasy sky.
Thin wispy clouds.
All of them begin with the same procedural building blocks.
What We Learned
Today we created our first procedural cloud shader.
By combining layered FBM, smooth transitions, slow animation, and a sky gradient, we generated a convincing sky entirely from mathematics.
This is one of the most practical procedural effects you'll encounter in shader programming.
Posted Using INLEO