This is a ray-parallel GPU pathtracer. I thought the most challenging part of the assignment was definitely stream compaction, which I implemented using the double buffer method. For each bounce of the ray, I mark which rays are dead (rays are dead if they hit the light or intersect no objects at all), and then do an inclusive scan based on the ray's status. When I have the scanned array that contains the new ray indices and how many rays are alive total, I build a new pool of rays based on this data, and then launch the next bounce with less rays to account for. The number of blocks used in the pathtracer kernel decreases each bounce since I calculated the number of blocks needed based on how many alive rays there are per bounce.
I also did fresnel refraction using Schlick's approximation.
Broken stream compaction
Diffuse
Look how much difference antialiasing makes!
Diffuse, reflection, and Fresnel refraction
Performance evaluation of ray parallel pathtracing with stream compaction vs. pixel parallel pathtracing.
Video link:
https://vimeo.com/user10815579
For stream compaction, I used the pseudocode from the class slides.
I referred to http://www.cs.unc.edu/~rademach/xroads-RT/RTarticle.html to do refraction and the wikipedia page to do Schlick's approximation.