Ray Tracer
A path tracer in pure C++ that reads its scenes from JSON and renders them three ways: direct illumination, supersampled anti-aliasing, and path-traced global illumination.
Written for COMP 371 at Concordia University, in February and March 2024. The
course supplies main.cpp, the test scenes and the libraries; everything behind
the interface it expects is in
src/ — about
1,100 lines of C++ across geometry, lights, the parser and the tracer itself.
The only dependencies are Eigen3 for the vector maths and nlohmann::json for reading scenes. No rendering library, no scene graph framework: a scene is a JSON file naming its geometry, its lights and the options to render it under, and the output is a PPM image.
Direct illumination
Spheres and rectangles, point and area lights, Phong shading with shadow rays.
This is the whole renderer with globalillum off.

Anti-aliasing
The same scene with antialiasing on: several samples per pixel, jittered
within the pixel and averaged. The difference is only visible at the edges,
it is the cheapest of the three features to implement and
the one a reader notices last.

Global illumination
globalillum switches the renderer from shading a hit to path tracing it. Rays
bounce until maxbounces runs out or Russian-roulette termination stops them at
probterminate, so the cost is bounded without cutting every path at the same
depth.

The Cornell box is the standard way to show it working, and the reason is the colour on the white surfaces: nothing in the scene is tinted green or red except the two side walls, so any green on the floor arrived there by bouncing.
What it is not
It is a course project, kept because the three renders above are a compact demonstration of what changes between the three techniques. It is single threaded, it renders spheres and rectangles only, and the acceleration structure is a loop over every object in the scene.
The source is on GitHub, GPL-3.0. The files the course provided are unmodified, as the evaluation required.