Monte-Carlo Path Tracing written in C++/CUDA
Path tracing is a render technique that simulates the interactions between rays from light sources and objects in the scene.
In order to get a rendered image of a 3D scene, for example the diamond images as the post’s cover, we essentially:
- Shoot rays rays from the positions of each pixel, through camera, to the scene;
- If a ray hits an object, then based on the material of the object’s surface:
- The ray bounces off randomly if the object is of diffusive material, which basically creates a new ray starts from the intersection with direction randomly distributed in a hemisphere;
- The ray bounces off only through the reflective direction if the object is of reflective material;
- The ray enters the object if the object is refractive, its direction changes according to the object’s index of refraction (eta).
- Repeat step 2. where rays keep bouncing off from a surface to another surface.
- A ray is terminated if:
- It reaches a light source;
- It hits nothing, means it will not do any contribution to the result image;
- It has bounced off enough times (or so-called depth), you can think this as a ray’s energy is all consumed.
- When all rays are terminated, we gather and average their colors and create a image based on it.
From the path-tracing procedures described above, we can get the sense that ‘Path Tracing’ is trying to simulate the stochastic phenomenon when light hits objects, which is also known and described by BSDFs, by shooting a lot of rays a lot of times into the scene, and approximate the continuous probability distribution by enough large number of discrete sampling. The best about Path Tracing is that the rays coming about from different pixels are independent, so we can use the power of GPU to run multiple threads, each carrying a ray, simultaneously on GPU.