As a 2 week project in Brown’s graduate graphics class, I implemented Path Tracing in C++ and Eigen. This method is physically accurate unlike a regular ray tracer, and involves tracing light paths from the camera and surfaces to perform Monte-Carlo integration for a surface’s luminescence.
The program supports diffuse, glossy, mirrored, and refractive materials. Since path tracing is expensive, I optimized rendering time by I using OpenMP to parallelize parts of the computation as well as a Bounding Volume Hierarchy to speed up ray intersection.
For lower variance in our light sampling, I splitted integrating for direct and indirect lighting. For direct, the sensible thing is to shoot rays directly at a random point on a randomly sampled light source, whereas for indirect lighting, we recursively trace paths. The result is a much smoother render with the same sample per pixel count.
For sampling light bounces, I sampled porpotional to the BRDF (Bidirectional reflectance distribution function) instead of uniformly over the hemisphere tangent to the surface. This is essential to get good renders of specular materials.
Lastly, I threw in depth of field and attenuated the refracted light for more realistic looking renders.