In fall of 2021, I took the class 6.837, titled Computer Graphics, which involved learning about as well as implementing some of the techniques for rendering images. One topic that we covered is path tracing, which essentially consists of calulating the color of each pixel in a rendered output by bouncing rays randomly around the 3D scene, and aggregating the result. A visual of the algorithm from one of the class slides is here:
Path tracing tends to be quite slow, but the results after waiting for a render can be quite realistic. For the final project, I worked with another student, and we implemented a path tracer that showed the process updating at each step (basically, as each pixel gets more paths sent through it, that pixel converges on what it’s final color should be).
There have been other implementations of this done before, but we learned a ton about how difficult debugging, and trying to make use of the GPU can be. For our project, we rendered the image using one monster fragment shader (definitely a hack), so the entire path tracing algorithm for a single pixel ran on a single core in the GPU; there are serious limitations with doing this, but it was fun to discover and work around those limitaions. For instance, recursion is not allowed in shaders, so everything had to be done iteravely.
Below is what the final product looked like (this is running at ~4x speed what it was on my MacBook, but you can see how the 3D render of the room starts to slowly come into view).
And this is the final output after 15 seconds without moving the scene looks like (whenever the scene is moved, the entire algorithm has to start over). Clearly, there are some artifacts, and we probably had a bug somewhere, but overall the results were neat.