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.