The second big project for my Advanced Computer Graphics class was to build a path tracer in C++. The following scenes are all custom and rendered with 400 samples per pixel and a recursion depth of eight.

This scene contains four differently-colored transmissive spheres and three reflective spheres of different roughness, all on a textured tile floor.

For the varying roughness of the reflective spheres, I implemented a microfacet BRDF, which uses a Trowbridge-Reitz distribution. The reflective and transmissive surfaces use Fresnel reflection coefficients for dielectric surfaces.

This scene contains a reflective sphere (with a microfacet roughness of 0.05) and two Lambert-shaded cubes.

For diffuse surfaces, I implemented both Lambert and Oren-Nayar BRDFs.

This scene has two reflective cubes, Lambert-shaded spheres, and a brick textured floor. It also has three lights — a blue one above left, a yellow one above right, and a white one right behind the camera.

In order to reduce variance, I implemented multiple importance sampling. This uses a power heuristic to weight the BSDF and light source samples when evaluating the Light Transport Equation.

For my final project, I chose to implement volumetric rendering, which allows for homogenous particle interactions.

To show off the particles in the volumetric rendering, I implemented a spotlight.

I had some extra time on the final project, so I also implemented an implicit surface. This is a tangle cube, and the implicit surface calculations use ray marching.

I also implemented a point light in order to create the effect of a light shining out from inside of the shape.