Advanced shaders · lesson 4 of 19 · Advanced · about 5 min

Ocean 4: foam, fine ripples and haze

You will build: Add two small high-frequency waves, whitecap foam with lacy edges, and distance haze to the finished sea.

The picture produced by the shader in the lesson "Ocean 4: foam, fine ripples and haze"
The target picture. In the lesson you write the shader that draws it, and a match bar shows how close you are.

Three more touches turn a nice sea into a convincing one.

1. Fine ripples. Two more waves with very small amplitude but high frequency add the little ripples that catch the light. (They are invisible as a shape, but huge for the normals.)

2. Foam. Whitecaps form on the tops of waves. Foam where the height is large, but not as a clean blob: add a noise value to the height before the threshold so the edge becomes lacy: smoothstep(0.15, 0.25, h + (lace - 0.5) * 0.22). The noise scrolls a little with time so the foam seems to drift.

3. Haze. Distant water loses contrast in the air: blend towards the horizon color with distance, 1.0 - exp(-t * 0.012). This one line is what makes the picture feel big. (The same trick, called fog, works in every 3D scene.)

float lace = fbm2(pos.xz * 3.5 + float2(time * 0.3, 0.0));
float foam = smoothstep(0.15, 0.25, h + (lace - 0.5) * 0.22);
col = lerp(col, float3(0.95, 0.97, 1.0), foam * 0.85);
col = lerp(col, float3(0.75, 0.82, 0.9), 1.0 - exp(-t * 0.012));

The numbers you need

Everything the picture depends on is given, so the challenge is the code, not guessing.

Extra waves
0.02, (-0.85, 0.52), 9.7, 4.0 | 0.012, (0.30, 0.95), 15.0, 5.2 (add them inside waveH before the return)
Lace
fbm2(pos.xz * 3.5 + float2(time * 0.3, 0.0))
Foam
smoothstep(0.15, 0.25, h + (lace - 0.5) * 0.22), color float3(0.95, 0.97, 1.0) at 85%
Haze
lerp(col, float3(0.75, 0.82, 0.9), 1.0 - exp(-t * 0.012)) at the very end
Everything else
as in Ocean 3

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