3D with raymarching · lesson 6 of 7 · Intermediate · about 5 min

3D, step 5: which way does the surface face?

You will build: Ray march the sphere (smart steps) and colour hit pixels by their normal; misses stay dark.

The picture produced by the shader in the lesson "3D, step 5: which way does the surface face?"
The target picture. In the lesson you write the shader that draws it, and a match bar shows how close you are.

You can now find the spot where each ray touches the sphere: pos = ro + rd * t. To light it we need the normal: the direction the surface faces at that spot.

For a sphere centred at the origin the answer is easy: the surface faces straight away from the centre, so the normal is just the position, normalized: n = normalize(pos).

Show it as a colour with the normal-colour trick: 0.5 + 0.5 * n. (You saw the same picture in the fake-3D sphere lesson, but this time it comes from a real ray hit.)

float3 col = float3(0.05, 0.06, 0.1);       // background
if (t < 12.0)                               // the ray hit something
{
    float3 pos = ro + rd * t;               // the spot it hit
    float3 n = normalize(pos);              // sphere at the origin: normal = direction from the centre
    col = 0.5 + 0.5 * n;
}

Next lesson adds the light and a function that works out the normal for any shape, not just spheres.

The numbers you need

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

Setup + loop
same as the last lesson (24 iterations, d = length(ro + rd * t) - 1.0, break if d < 0.001 or t > 12.0)
Hit?
t < 12.0
Normal
n = normalize(ro + rd * t)
Colour
0.5 + 0.5 * n, miss: float3(0.05, 0.06, 0.1)

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

Concept explainers with a live example: ray marching.

Part of the learning path: From zero to ray marching.