Advanced shaders · lesson 5 of 19 · Advanced · about 5 min
Clouds 1: noise in three dimensions
You will build: Show a moving slice through 3D fractal noise: white clouds on a blue sky.
A cloud is not a surface, it is a volume: a soft puff of tiny water droplets that is thicker in some places than others. To describe a volume we need a number for every point in 3D space: the density.
You already know 2D value noise. The 3D version is the same idea one dimension up: random numbers at the corners of a cube, blended smoothly in x, y and z. The only new helper is a hash that eats a float3 and gives back a number between 0 and 1. (This hash uses no sin(), so it gives the same answer on every graphics card.)
Stack four layers of it at doubling frequency and you get fbm3, fractal noise: big billows with smaller billows on them.
A neat way to see a 3D function is to take a slice of it. Use (x, y) of the screen and a slowly growing time as the third coordinate. As time passes the slice moves through the volume, and the blobs grow, split and melt away, like a cloud forming.
float d = fbm3(float3(p, time * 0.3)); float c = smoothstep(0.42, 0.62, d); // cut the noise: only the high parts become cloud float3 col = lerp(float3(0.3, 0.55, 0.9), float3(1.0, 1.0, 1.0), c);
The numbers you need
Everything the picture depends on is given, so the challenge is the code, not guessing.
- Position
p = (uv - 0.5) * float2(aspect, 1.0) * 4.0- Density
d = fbm3(float3(p, time * 0.3))- Cloud amount
smoothstep(0.42, 0.62, d)- Color
lerp(float3(0.3, 0.55, 0.9), float3(1.0, 1.0, 1.0), cloud amount)
Try it in your own language
The lesson is written once and shown in every language. Pick yours: Unity (Built-in), Unity (URP), Unreal, Shadertoy / WebGL, OpenGL (LWJGL, raylib), three.js, GameMaker, LÖVE (Lua), Godot, Apple (iOS, macOS), WebGPU / Bevy.
Start coding