Jesus Gutierrez, [email protected]

Project Description

Photon Mapping

For my final project I wanted to incorporate photon mapping into my renderer. Photon mapping was interesting to me because it allows for the rendering of caustics in a straightforward and sample efficient way.

The setup for basic photon mapping involves several steps. First, photon tracing is a process similar to ray tracing where photons are traced from a light source and deposited at diffuse surfaces. These deposited photons form a photon map, which is used to evaluate irradiance at nearby points. In order for the photon map to be useful, it is first organized into a spatial data structure in order to be queried faster. Often a KD-Tree is used, so that is what I went with. Photons are sorted along some maximal axis and then split along that axis in order to repeat the process recursively. This forms a well-balanced tree that helps speed up photon search. At render time, this photon map is used to search for nearby photons at an intersected surface using K-nearest neighbors to approximate irradiance at that point.

The implementation I went with involves evaluating radiance with photon mapping only where it is best suited and using MC path tracing everywhere else. This requires having the ability to calculate radiance in four separate ways. Direct lighting and specular/glossy reflections are best evaluated using path tracing as photon mapping is highly inefficient here. It does not take visibility into account and glossy/specular reflections are either too expensive on memory or impossible to calculate with a photon map. This is because the chance of a photon at a mirror surface having the reflection direction of an incoming ray is near 0 or 0 for perfectly smooth surfaces.

So that leaves photon mapping to help evaluate global illumination in the form of indirect diffuse bounces and to evaluate caustics. For global illumination, from a diffuse surface a ray is cast in a direction according to the material properties and if it hits another diffuse surface, the radiance from that direction is calculated using the global photon map. Evaluating caustics using the caustic photon map is discussed later on.

One of the biggest challenges I had was figuring how to get photon mapping to closely follow the work that we had previously done in the class so that I could have a better reference for what was correct. For example, a lot of resources on photon mapping included using methods of Russian Roulette that were different from what we used. The images below show results from standard path tracing compared to those I got from photon mapping.

Diffuse scene with photon mapping (spp 64)

Diffuse scene with photon mapping (spp 64)

Diffuse scene with path tracing (spp 64)

Diffuse scene with path tracing (spp 64)

Photon mapped GGX scene (spp 32)

Photon mapped GGX scene (spp 32)

Path traced GGX scene (spp 32)

Path traced GGX scene (spp 32)

Caustics

The next step was to get to get caustics working. Caustics are a phenomenon that occur due to the focusing of light under certain conditions such as transmission through glass, or reflection from conductors. This effect is typically poorly captured by traditional path tracing, and so augmenting the rendering process with a photon map is ideal for visualizing it.

The first part of the process was implementing a transmissive material that could focus light. I went with a specular/transmissive BSDF described in PBRT that is not physically accurate, but plausible. This was simpler to implement than physically based BSDFs but one drawback to this is that since the material involves a delta distribution, direct lighting is impossible to get samples for, so reflections are not high quality at low sample counts.

For the evaluation of lighting from caustics it is beneficial to have a separate photon map specifically for them. This is because caustics are often concentrated in small areas and a lot more photons would be needed if only using the global photon map. Photon tracing for the caustics photon map is similar to the global one, except photons are only stored directly after they have hit a specular surface. This way you are able to capture diffuse lighting going through a transmissive material.

As a reference for refracted caustics, I had to use path tracing with next event estimation off, as it would require changing the NEE path tracing code otherwise. The following images use gamma correction, and 100,000 global photons, with 1,000,000 caustic photons for the Cornell scene and 10,000,000 for the dragon scene.

PM NEE On (spp 32)

PM NEE On (spp 32)

PT NEE Off (spp 500)

PT NEE Off (spp 500)

PT NEE On (spp 32)

PT NEE On (spp 32)

Caustics from a reflective material (spp 32)

Caustics from a reflective material (spp 32)

Similar effect is not captured in path tracing

Similar effect is not captured in path tracing

Dragon with a copper like material (spp 64)

Dragon with a copper like material (spp 64)

A few interesting caustic angles (spp 128)

A few interesting caustic angles (spp 128)

Documentation