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

Ocean 1: a surface made of waves

You will build: Write waveH(): the sum of five moving sine waves. Show it from above as a color map.

The picture produced by the shader in the lesson "Ocean 1: a surface made of waves"
The target picture. In the lesson you write the shader that draws it, and a match bar shows how close you are.

Every game ocean starts with the same idea: the water is a height field. For every spot (x, z) on the sea there is one number, the height h of the surface there. Animate that number and the sea moves.

The simplest wave is a sine: sin(position * frequency + time * speed). The position has to be measured along the direction the wave travels, and that is exactly what a dot product gives you: dot(xz, direction).

One sine looks like a corrugated roof. The trick that makes it look like water is to add several, each with its own direction, frequency, speed and a smaller amplitude: long slow swells with short fast ripples riding on them.

float waveH(float2 xz)
{
    float h = 0.0;
    h += 0.30 * sin(dot(xz, float2(0.80, 0.60)) * 0.9 + time * 1.1);
    h += 0.20 * sin(dot(xz, float2(-0.60, 0.80)) * 1.4 + time * 1.3);
    // ...three more, smaller and faster
    return h * 0.5;
}

Here you draw the height field seen from above, as a map: dark where the water is low, bright where it is high. Next lesson you stand in it.

The numbers you need

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

Waves (amplitude, direction, frequency, speed)
0.30, (0.80, 0.60), 0.9, 1.1 | 0.20, (-0.60, 0.80), 1.4, 1.3 | 0.12, (0.95, -0.30), 2.3, 1.8 | 0.07, (-0.20, -0.98), 3.7, 2.4 | 0.04, (0.55, 0.83), 6.1, 3.1
Each wave
amplitude * sin(dot(xz, direction) * frequency + time * speed)
Result
h = sum of the waves * 0.5
Position
p = (uv - 0.5) * float2(aspect, 1.0) * 10.0
Color
lerp(float3(0.02, 0.1, 0.18), float3(0.45, 0.85, 0.9), saturate(h * 1.6 + 0.5))

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

Go deeper

Part of the learning path: Realistic water and sky.