A ray tracer built from first principles in C++ — no rendering engine, no graphics library doing the math for you, just vectors, rays, and a lot of intersection tests.
Why build a renderer by hand
It's one thing to use a rendering engine and another to understand why the image it produces looks the way it does. Starting from Peter Shirley's Ray Tracing in One Weekend as a base and extending it was a way to actually own that understanding — every reflection, shadow, and highlight in the output traces back to code I wrote and can explain line by line.
The core pipeline
The engine is split into small, single-purpose modules — vec3 for the 3D math, ray for ray representation, color for output — that compose into the main render loop: cast a ray per pixel, test it against every object in the scene for intersection, and shade the closest hit using a Phong lighting model. Shadow rays and reflection rays extend that same intersection logic recursively, which is what gives the output actual depth and shine rather than flat-shaded shapes.
Keeping it modular
Because intersection, shading, and scene management are cleanly separated, adding a new primitive or a new material later doesn't mean touching the render loop itself — it slots into the existing interfaces. That structure mattered more here than raw performance did; the goal was a codebase I could keep extending, not just one working image.