Introduction

Every photorealistic image in a film or video game is a lie — a calculated one. The computer never simulates how light actually travels, flooding out from lamps and bouncing around until some lands in your eye. That would be impossibly slow. Instead it cheats: for each pixel on screen, it shoots a single ray backwards, from the camera into the scene, and asks "what did this pixel see?"

That backwards ray hits something — a sphere, a wall, a mirror. If the surface is shiny, the algorithm spawns a reflected ray and follows it. If the surface is glass, it spawns a refracted ray and bends it. Each bounce can spawn more rays. The algorithm is elegantly recursive: the color of a pixel is the color of the nearest hit, which depends on the color of the reflected ray, which depends on the color of whatever that ray hits, and so on until a ray escapes the scene or hits a light source.

This simple recursive idea, first described by Arthur Appel in 1968 and extended by Turner Whitted in 1980, is the engine behind nearly every photorealistic render you have ever seen. Its computational cost — one recursive ray tree per pixel — is the tradeoff that kept it out of real-time graphics for four decades.

Trace the Spheres

Below is a miniature ray tracer running in your browser. It shoots one ray per pixel into a scene of colored spheres sitting on a floor plane, computing reflections and a point light source. Drag the Reflections slider to limit how many times a ray can bounce, and watch the mirror world deepen.

<!-- {{c_html_comment}} -->
<div class="controls">
  <label>{{lbl_reflections}} <span id="depthVal">3</span>
    <input type="range" id="depthSlider" min="0" max="5" value="3">
  </label>
  <button id="renderBtn" type="button">{{btn_render}}</button>
</div>
<canvas id="canvas" width="360" height="280" title="{{canvas_title}}"></canvas>
<div id="status" class="status"></div>
/* {{c_css_comment}} */
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; margin: 0; background: #0d1117; color: #e6edf3; }
.controls { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; padding: .5rem 0 .6rem; }
label { font-size: .85rem; display: flex; align-items: center; gap: .4rem; }
input[type=range] { width: 110px; accent-color: #58a6ff; }
button { font: 600 13px system-ui; padding: .35rem .8rem; border: 1px solid #58a6ff;
         background: #1f6feb; color: #fff; border-radius: 6px; cursor: pointer; }
button:hover { background: #388bfd; }
canvas { display: block; border-radius: 6px; border: 1px solid #30363d; cursor: default; }
.status { font-size: .8rem; color: #8b949e; margin-top: .4rem; min-height: 1.2em; }
// Code not found

Notice how setting reflections to 0 gives flat, unlit colors; each extra bounce adds mirror depth and costs proportionally more computation. A real production renderer uses the same recursive loop — just with physically accurate materials, area lights, and thousands of samples per pixel for Monte Carlo noise reduction.

The Real Complexity

Ray tracing is not a hard problem in the complexity-theoretic sense — it is not NP-complete or undecidable. But it is expensive, and understanding why reveals the entire architecture of modern renderers.

  • Per pixel, per bounce: a scene with W×HW \times H pixels and a maximum depth of dd bounces requires up to WHrdW \cdot H \cdot r^{d} ray–object intersection tests, where rr is the average branching factor (number of secondary rays per hit). Even with r=1r = 1 (one reflection per hit), depth-10 rendering of a 1920×10801920 \times 1080 image means over 20 million intersection tests.
  • Intersection cost: naively testing a ray against nn objects is O(n)O(n). With a Bounding Volume Hierarchy (BVH) — a tree of bounding boxes — this drops to O(logn)O(\log n), making scenes with millions of triangles tractable.
  • Embarrassingly parallel: every pixel's ray tree is completely independent. This is the property that lets modern GPUs — with thousands of shader cores — trace millions of rays simultaneously. NVIDIA's RTX hardware adds dedicated ray-tracing cores that walk the BVH at hardware speed.
  • Path tracing and noise: the physically correct extension, path tracing, picks one random secondary ray at each bounce instead of many, reducing cost per pixel to O(d)O(d) but introducing noise. Convergence requires O(n)O(n) samples per pixel, where the variance falls as 1/n1/\sqrt{n}.

So the algorithm scales as: more pixels ×\times more bounces ×\times more objects == more time, all of it parallelizable. The hard part is not algorithmic complexity — it is fitting enough computation into a 16-millisecond frame budget.

Where It Matters

The recursive ray idea propagated far beyond academic rendering papers:

  • Film and animation: every Pixar, DreamWorks, and Marvel visual-effects shot since the 1990s is rendered with ray- or path-tracing engines (RenderMan, Arnold, V-Ray). A single frame can take hours even on a render farm.
  • Real-time games: NVIDIA's RTX 20-series (2018) put hardware BVH traversal on consumer GPUs, making real-time ray-traced reflections, shadows, and ambient occlusion practical for games like Cyberpunk 2077 and Minecraft RTX.
  • Product visualization and architecture: car manufacturers, furniture brands, and architects use offline ray tracers to produce photorealistic renders of products before they are built — indistinguishable from photography.
  • Scientific visualization: volumetric rendering of CT/MRI data, simulating light through atmospheric models, and radiosity in building energy simulations all borrow ray-tracing mathematics.
  • Global illumination research: path tracing, photon mapping, bidirectional path tracing, and Metropolis light transport are all variants that refine the core idea toward physically accurate light simulation.

Understanding ray tracing is the entry point to the whole field of physically based rendering — the same math that lights Monte Carlo simulations, powers neural network denoising, and underpins every pixel of modern cinema.

Conclusion

Ray tracing is one of those rare ideas that is both conceptually simple and practically profound. Shoot a ray backwards from the camera, ask what it hits, recurse on reflections and refractions — that is the whole algorithm, unchanged since Whitted wrote it down in 1980. What changed over forty years was hardware: the billions of parallel floating-point units on a modern GPU finally make the arithmetic fast enough to run in a game frame.

The deeper lesson is that embarrassing parallelism is as valuable as algorithmic cleverness. Ray tracing did not become fast because someone found a smarter algorithm — it became fast because engineers built hardware that matches the structure of the problem: independent rays, independent pixels, massively parallel. Next time a mirror reflection catches your eye in a game, remember: somewhere a tiny program shot a ray at that mirror, asked what the reflection saw, and recursed until the answer was a color.

Share this article

Pick a channel — or use your device's native share sheet.

Comments

Loading comments...

https://www.kipuhub.com/en/article/ray-tracing/Content licensed under CC BY-NC 4.0.