Volumetric Photon Mapping

with Peter P

Spring 2012, Stanford CS348B

The Project

Our goal for this project was to use volumetric photon mapping to render the body of a glass frog.

Glass frogs have very translucent skin so it is important to model the scattering of light beneath the surface in order to achieve a realistic look. This effect is especially important at the extremities, where the skin is a few shades lighter than the rest of the body and other parts of the frog are visible from behind.

Volumetric Photon Mapping

Volumetric photon mapping is a technique used to simulate the scatterning of light within participating media such as fog or silty water. Since the insides of a glass frog look like jello -- foggy and slightly murky but mostly transparent-- we decided that this would be a good technique to use.

Radiance Estimation

We followed the algorithm outlined in Jensen et. al. and created a custom volume integrator on top of the pbrt framework. For simplicity, we kept our 3D volume integrator separate from pbrt's 2D surface integrator. The separation led to an underestimation of the caustic radiance at volume-surface boundaries, but our scene did not have many of these areas so the impact was minimal.

To estimate radiance, we used Jensen's equation 10.8:

jensen formula

The first term in the equation is the contribution of the light source, which we modeled after the single scatter integrator in pbrt. The second term represents the gathering of light at the current point in the ray and the third term represents the attenuation of light from the previous point in the ray. As we march along the ray, we attempt to find the same number of photons at each step, and increase the search radius until we reach our target value.

Volume Clipping

The public version of pbrt only supported axis-aligned and voxel volumes. Since the body of our frog enclosed a non-trivial, non-convex volume, we joined a generic volume with a clipping primitive to help identify whether points were inside or outside of the body. To determine if a point is inside the volume, we cast a ray toward the clipping surface. Assuming that the surface does not intersect itself, if the normal of the surface points away from the direction of the ray, we are inside of the volume. Otherwise, we are outside.

The image to the right tests our clipping code. A glass sphere is suspended in a homogenous volume with a light shining from the top. None of the green particles enter the sphere and the light focuses through it to produce a nice caustic underneath.

Skin Texture

In order to give the skin a bumpy appearance, we wrote a few scripts in Matlab to generate a texture map. The first script randomly generated a height field given the desired number and of bumps and their diameter. We then used a Gaussian distribution to create the rounded fall-off, and converted the height field into a normal map by splitting each cell into two triangles and calculating the normals at each vertex. Since the bumps on the skin of a frog vary in height and size,we combined several height fields together before generating the final texture.


We created our own models for the frog and lily. Since neither of us had any modeling experience coming in, this step was rather tricky. For details on how I made the lily, please visit my modeling page here.

Here's a quick screenshot of the lily petal wireframe

...and the beginnings of the frog body in Blender

Putting it all together

In the reference image, the frog's skin had a shiny outer layer so we decided to use a glass material for the surface of the skin. We didn't have time to experiment with different materials to make the flower look realistic, so we went for a glass material for that as well. We then filled the frog with a homogenous volume to simulate the scattering of light on the inside. We repeated this with the petals as well to give the glass two colors.


As this was a two-week project, we did not have time to model the opaque and diffuse organs inside the frog, so its body remained empty. Without anything to stop the light from refracting all the way through, the frog came out looking a bit empty and more like a yummy gummy frog.