What Is Ray Tracing?
Posted on Thu 01 October 2026 in tech
| Z-buffer | Ray tracer |
|---|---|
![]() |
![]() |
The two renders above show one scene. gman's z-buffer shades each surface from its lights alone and never asks what stands between them, so nothing casts a shadow.
Shadows, mirrors and glass all come from one move: fire a ray and see what it hits.
One ray per pixel
A ray tracer follows light from the eye to the lamp. Almost none of the light leaving a lamp reaches your eye, and a light path is the same in either direction, so the renderer starts where the answer is needed. There is one ray from the eye through each pixel. The ray asks one question: what is the first surface you hit?
What a ray hits
A ray is an arrow with a start point O and a direction D. The point t steps along it is O + tD. To find what it hits, ask each object how far along the ray it sits, and keep the smallest distance.
For a sphere of center C and radius R, a point P is on the surface when |P − C|² = R². Put P = O + tD into that and the condition becomes a quadratic in t:
(D·D) t² + 2 D·(O − C) t + |O − C|² − R² = 0The roots are the hits. The smaller positive one is the first surface the ray meets; a ray that misses has no roots. Every primitive gman draws has its own intersection test.
Shadows, mirrors and glass
From each nearest hit, the ray tracer recurses by firing another ray toward each light. If the ray reaches the light, the light adds its intensity to the point; if something opaque is in the way, the light adds nothing and the point is in shadow.
A reflective surface fires another ray in the reflected direction. gman's mirror shader is C++, but in RenderMan's shading language it is one line:
Ci = Os * Cs * Kr * trace(P, R);
R is the reflected direction and trace() fires a ray along it. Whatever that ray finds, the mirror returns scaled by Kr. If it finds another mirror, that one fires a ray of its own.

Glass sends light both ways: part reflects and the rest bends through the surface, so one hit fires two rays. Face-on, glass reflects about 4 percent of the light; at a grazing angle, nearly all of it, which is why the edges of a glass vase look like mirrors.

Each ray can spawn more rays, so a pixel expands into a tree of rays. gman follows Turner Whitted's recursive scheme: rays nest four deep, and a branch that reaches the fourth bounce gets the background color.
One term per bounce
One equation describes all the light in a scene:
L = Le + K*LL is that light, Le the light the lamps emit and K what one bounce does to light. L appears on both sides because reflected light is still light, and it reflects again. Substitute L into itself and the equation unrolls, one term per bounce:
L = Le + K*Le + K²*Le + ⋯Le is light straight from a lamp, KLe light that has bounced once, K²Le light that has bounced twice.
The terms it skips
A Whitted ray tracer follows light only where the direction is certain: toward a light, off a mirror and through glass. The light a matte wall passes to another matte wall scatters in every direction, and following it would take a fan of rays at every hit. The ray tracer drops those terms. The vase scene stands in for them with LightSource "ambientlight" 1 "intensity" [0.38], one constant brightness added everywhere, a guess.
Radiosity computes those terms, and it is the next article in this series.
Try it
Install gman with the tarball's install.sh, as the README shows. Then, from the unpacked folder:
gman -r gmanraytracer samples/vase.rib
That writes vase.png, the ray-traced render above, in about 2.4 seconds on an Apple M3 Max. Plain gman samples/vase.rib renders the z-buffer preview. The gman page shows the one-line edits that turn the vase to glass and the dome to a mirror.
Links
- gman on GitHub, with its releases and changelog
- The gman page
- The RenderMan Interface Specification 3.2, the RIB and C API gman implements

