My favorite part of the course dealt with rendering techniques, I enjoyed writing a ray tracer for the course, so I jumped at the chance to enhance that ray tracer via Photon Mapping.
The idea behind photon mapping is simple, cast photons from light sources and collect them from the surfaces they land on to estimate the color at that point. Here is one of my final images. My implementation is largely inspired by this source describing the theory and possible implementations of photon mapping: http://penguin.ewu.edu.
The first step when photon mapping is casting the photons into the scene. This is an image showing where my photons are cast into the scene. What is shown is orthogonally projected, so that's why the left and right walls, as well as the floor, are represented by single lines. Notice that some photons are reflected off specular surfaces, such as the red and green walls, but the vast majority remain at the first point they come into contact with.
The next step is collecting the photons to estimate color at a given area. For each point of intersection given during the raytracing step, I collect all the photons in a given area. These photons are used to estimate the color given the power they contain from their original light source and the color they have collected both from their light source and any surfaces they have bounced off of. In this error image you can see the area I am pooling photons from, represented by the small circles on each surface.
Here are a few final images and their associated rendering/photon mapping criteria:
Cast Photons: 160000
Collection Area: 3*
*Spheres have radius of 3 for scale
Cast Photons: 160000
Collection Area: 3*
*Smaller spheres have radius of 3 for scale
Cast Photons: 250000
Collection Area: 3*
*Smaller spheres have radius of 3 for scale
I really enjoyed this project and plan on continuing to work with it. I have a few things I'd like to change and a few things I'd like to add to it.
In the paper we read on photon mapping, it discussed two possible ways of collecting photons: either gathering all photons in a given area, or gathering the N nearest photons. I chose to gather all photons over a given area for several reasons: I thought it would give nicer shadows and I wanted to see what it looked like as the paper did it the other way. As you can see in this image though, it can cause problems when two objects are too close to one another. So I plan on going back and changing my data structure to allow me to find the N nearest photons.
While my program does cast Caustic photons at specular objects in a second pass, I couldn't find a way to keep them from ending up in total internal reflection inside of spheres. This resulted in an endless loop that created an unusable photon map. I plan on fixing this as well as updating my ray tracing so that I can represent refractive and reflective objects, as currently I only render a single pass.