Stand a matte white card next to a bright red mug in the sun and the card's edge blushes pink. Nothing touched it; no red paint was applied. What reached the card was sunlight that had already bounced off the mug, picking up its colour on the way. That single everyday observation is the whole subject of this page. Real light does not stop at the first surface it strikes — it ricochets around a room, spilling colour, softening shadows and filling every crevice, until the scene settles into the rich, coherent look our eyes trust. Capturing all of that bouncing is called global illumination, and the cleanest way to compute it is a beautifully simple algorithm called path tracing.
This lesson builds on ordinary
Split the light arriving at a point on a surface into two piles. Direct lighting is what comes straight from a light source — the sun, a lamp, a window. It is easy: draw a line from the point to the light, check nothing blocks it, done. Indirect lighting is everything that reached the point after bouncing off one or more other surfaces first. That second pile is where all the visual richness hides:
Global illumination (GI) is simply the name for computing that second pile — the light that has bounced. Direct lighting alone gives you a scene lit by a torch in a black void: crisp, hard, and lifeless. Add the bounces and the scene becomes a place.
In 1986 Jim Kajiya wrote down a single equation that says how much light leaves any point in any
direction, and it accounts for every bounce at once. The outgoing light
Read it left to right:
That nested, hemisphere-wide integral has no closed form for a real scene. Path tracing solves it the way you'd estimate any hopeless integral — with Monte Carlo: don't integrate, just sample. Rather than gather light from every incoming direction, pick one random direction, follow it, and let the average of many such random walks converge to the true value. The recipe for a single pixel:
There is no separate "lighting pass". The recursion is the light bouncing. A path that happens to strike a red wall then a white floor before finding the lamp is a photon's worth of colour bleed, computed by the very same loop that does everything else. Because the sampling is done honestly — with no shortcuts that skew the average — path tracing is unbiased: push enough samples through and it converges to the exact solution of the rendering equation, ground truth with no cheats.
Here is a single traced path through a tiny scene. A ray leaves the camera, strikes the red wall, scatters to the floor (carrying a little red with it), then bounces up and finds the light. At that moment the whole path lights up: the pixel receives the lamp's energy, tinted by every surface the path touched on the way. Trace thousands of such paths, each taking a different random turn at each bounce, and their average is the pixel's true colour.
The more bounces a path is allowed, the more indirect light it can capture — one bounce gives you direct lighting only, two bounces bring in first-order colour bleed, and deeper paths fill the subtle inter-reflections that make a room feel continuous. Each extra bounce contributes a little less, which is what makes the next trick — knowing when to stop — safe.
Paths could bounce forever, but each bounce loses energy, so far-flung bounces barely matter. Simply
capping the depth would throw away that energy and bias the result (too dark). The unbiased
fix is Russian roulette: at each bounce, with probability
The expectation is untouched — that little algebra is the whole reason path tracing can terminate honestly.
A pure random bounce only contributes when it happens to hit a light. For a small lamp that is a rare, lucky event, so most paths carry nothing and the image is grainy. Next-event estimation (NEE) fixes this: at every bounce, in addition to the random continuation ray, send a ray directly toward a light source and, if it is unblocked, add that light's direct contribution then and there. Now every single bounce harvests some direct light instead of praying to stumble onto the source.
The random bounce is still there to gather indirect light; NEE just adds an explicit, deliberate sample of the direct term at each vertex, weighted so nothing is double-counted. It is the single biggest noise reduction in a basic path tracer — the difference between a usable image in minutes and a snowstorm.
Monte Carlo estimation converges, but the error falls off only as the square root of the sample count. Quadruple the paths per pixel and the noise halves:
That
Some effects are stubborn for a plain camera-side path tracer. Caustics — light focused through a wine glass onto a table — require a path that leaves the light, refracts through glass, and lands on the exact spot the eye is looking at; the odds of a camera path randomly finding that route are tiny. Specialised solvers exist for these:
For decades all of this was strictly offline — minutes to hours per frame. Then GPUs grew dedicated ray-tracing cores (NVIDIA's RTX and friends) that intersect rays against the scene in hardware, tens of billions per second, paired with AI denoisers that turn a handful of noisy samples into a clean frame. Path tracing at interactive rates — unthinkable in 2010 — now ships in real games. The algorithm never changed; the silicon caught up.
Follow a single path through a Cornell-box-style scene and see how it earns the pixel its colour. Take
a diffuse red wall with reflectance
Step 1 — camera ray. A ray leaves the eye through the pixel and hits the red wall at
point
Step 2 — sample a bounce. The wall is diffuse, so we sample a new direction with the
cosine-weighted distribution the BRDF prefers: directions near the surface normal are
more likely, directions near grazing less so. This importance-sampling choice makes the estimator
Step 3 — continue. The bounced ray travels to the white floor at
Step 4 — reach a light. The next bounce (or an NEE shadow ray) strikes the lamp,
radiance
Step 5 — average. One path is a wild, noisy guess. Fire
As
The algorithm is a page of code, but the
The GPU rasterizer that draws most real-time graphics answers one question per pixel — "what surface is visible here, and how is it lit directly?" It has no notion of a ray bouncing to a second surface, so it captures none of the indirect pile: no colour bleed, no true soft fill, no honest ambient occlusion. Left alone, rasterized frames look flat and plasticky — the tell-tale "old CGI" look. Everything indirect must be faked: a flat ambient term to lift the blacks, baked ambient-occlusion maps for the creases, pre-computed light probes or lightmaps for bounce colour. These approximations are fast and often convincing, but they are guesses, and they break when the scene moves.
Path tracing gets every one of those effects for free — they fall out of the same bounce loop
— but charges you in samples: at low counts the image is noisy, so you lean on the