CSE 168 Final Project: Photon Mapping

by Fred Birchmore

Title: “Wild Blue Yonder” AKA: “Zee Plane! Zee Plane!”

I gave this image two names. The first, and primary name, basically describes what you see –which is an ocean which is both “blue” and “yonder”. This also fits in with the military theme of the image. The second name illustrates the reasoning I put into creating this particular scene. I use the name “Zee Plane! Zee Plane!”, using the well known phrase said by the short guy on Fantasy Island. The reason I picked this name is because it is sort of a random name. The reason that you see this image before you today is that I've actually constructed many different scenes but none of them could be successfully exported and rendered. Therefore, a random scene deserves a random name.

If you just glance at this image really quickly, a few different thoughts might come to mind, such as “that looks nice...but what is it?” or “it looks kinda noisy” or, ideally, “wow, pretty!”. The reason this image is susceptible to receiving such a response is that because of all the problems that I ran into in creating a scene to render, I ended up only having 3 hours to render this final image. As a result, I had to lower the number of photons used, the number of final gather rays, and the number of jittered primary rays.


I made the cave by following the tutorial on caves from 3dcafe.com, written by Barry G.J. Driessen. I created a sky box on each side of the cave by creating planes and adding textures from scentednectar.com. I got the model of the f-18 from 3dcafe.com (I am not sure who made it, but if I find out I will give them credit). When rendering the scene, I made sure that the skybox textures, except for the floor, did not get shaded by my raytracer (since you can't light up the sky in the daytime by shining a light at it).


As for the other scenes I created, I ran into numerous problems with 3DStudio MAX. I am using the 30-day trial version. For some reason, 3Dstudio MAX will only export certain scenes into OBJ format. For some reason, it crashes when I try to export certain scenes. So, everytime I created a new scene, 3DStudio MAX ended up rejecting it. I therefore had to either start a new scene entirely from scratch, remove objects from the scene, or replace existing objects with different ones. I also had trouble finding models that 3DStudio MAX would import correctly. Much of the time, the models I loaded in were missing half of their triangles or the models were made in such a way that special material properties were used instead of extra triangles. Here are some of the scenes, shown in 3DStudio MAX's renderer, that I created but was unable to export:

The submarine was made by dam3d from dam3d.com, the plants were made by Drew Costigan at 3dplants.com, the fish are from http://toucan.web.infoseek.co.jp/3DCG/3ds/FishModelsE.html. I left the front viewing window off of the sub with the idea that I would replace it with a sphere that would refract light.

I made the cave using the same cave tutorial mentioned before. The submarine is the same used in the image above. The shark is from 3dcafe.com (I'm not sure who made it, but will give them credit if I find out)


I implemented photon mapping, using Dr.Jensen's code for the K-D Tree data structure. I used Dr. Sam Buss's code for loading texture maps. Here are some of the features that I added to my basic BSP-Tree raytracer, using the fanciest names possible:

*Jittering of Primary Rays using Stratified Sampling

*Final Gather Rays generated for indirect illumination using a random, hemispherical distribution

*Russian Roulette is used to determine if a photon is diffusely reflected, refracted, specularly reflected, or absorbed.

*A Separate Texture map for each object by using U,V coordinates to directly choose a diffuse color for an object

*Separate Material Properties per object


*Refraction (doesn't work properly)

Here are some images I generated along the way:

The tank was made by Oleg Pomoshnikov and was acquired from 3dcafe.com. It was rendered directly in a box.

This is the same tank, using only indirect illumination with no photon mapping and a low number of samples per pixel. Both tanks were added before photon mapping was implemented.

This is a box with Phong direct illumination (no photons) and indirect illumination from the global photon map using 2 million photons. 100 gather rays per sample are used. I believe that 16 primary rays are jittered.


3d modelling takes time: Generating a scene with no prior knowledge of 3D modelling is difficult and takes much longer than expected. It took so long that I was not able to show off some of the most important capabilities made possible by photon mapping.

Don't rely strictly on an image for debugging: Debugging a graphics application is not trivial just because it renders an image. I spent days and days just trying to get global illumination to “look right”. I would write some code, render an image, and if it didn't look right, I would change some code and repeat. I ended up being incorrect almost all of the time. Fortunately, Wojciech helped me get global illumination working. I would not have finished if it weren't for his help.