COS 526 – Assignment 3 – Photon Mapping

Abulhair Saparov

Photon emission

Two flags control how many photons are emitted: -global-energy and -caustic-energy. These both indicate the number of photons that are emitted per unit “intensity”. Photon tracing is done in two passes: one for all photon types, called “global”, and one for only caustic photons, where the photon must either do a specular bounce or a transmission before any other bounces. Photon emission was implemented for each of the light types:

point light

spot light

area light

directional light

Photon scattering/Russian roulette/BRDF importance sampling/photon storage

Scattering was implemented as described in the Jensen paper, with Russian roulette (power was recomputed accordingly at each bounce). The new direction of the photon at each bounce was computed probabilistically (sampling from the BRDF, depending on the type of bounce).




Multiple photon maps

Two photon maps were kept so that it was easy to increase/decrease the resolution of the caustic photons map relative to the resolution of the global map. As mentioned, these maps were constructed in two passes where in the caustic pass, if the first bounce was not a specular bounce or transmission, the photon was ignored.

global photon map (7412 photons)

caustic photon map (14416 photons)


global photon map (8591 photons)

caustic photon map (159369 photons)



I implemented a distribution ray tracer as described in the Jensen paper. Total radiance along a ray is the sum of radiance due to: direct illumination, specular/transmission, caustic illumination, and indirect illumination. To speed up rendering, I also implemented Greg Ward's irradiance cache mentioned in the Jensen paper. I tested with the Cornell box in cornell.scn (from and a custom scene in custom.scn with a glass sphere and glass box, illuminated by a spotlight. Another custom scene in custom2.scn with six spheres (some chrome and some glass) with a point light in the center.

direct illumination

photon map radiance

caustic illumination

indirect illumination

all radiance (with specular and transmission)

global photons: 733487, caustic photons: 778

total rays: 15790008, render time: 594.71 seconds


global photons: 87352, caustic photons: 4784141

total rays: 2231839, render time: 289.32 seconds


global photons: 959166, caustic photons: 4752532

total rays: 12298694, render time: 349.02 seconds


I implemented a cone and Gaussian filter as in the Jensen paper, but since I was using a small radius for the photon map radiance computation anyway, I did not notice any large differences in the final rendering. The following is the radiance estimate from the photon maps to highlight the differences.

no filtering

cone filter

Gaussian filter


Multiple rays were shot through each pixel (using stratified sampling) to reduce aliasing effects. The default is 4 (2x2).

1 ray per pixel

4 rays per pixel

9 rays per pixel

Art contest


global photons: 744211, caustic photons: 5650534

total rays: 14939737, render time: 1830.70 seconds