caustics in the cornell box

November 15th, 2006 by Bramz

It’s been more than a month since last update, so it’s time for a status report. I’ve been further playing with photon mapping and some nice shaders. The main additions to the photon mapper itself are the (ir)radiance caching when using the final gather step, and the caustics map.

The former was – I believe – originally suggested by Per Christensen in Faster Photon Map Global Illumination. The idea comes from the observation that when using final gathering, a lot of time is consumed by the radiance estimates where final gather rays hit. When you cache these estimates at selected positions, You can gain a factor of 5 to 10 in speed, while the error you get by using this approximation will hardly be noticeable due to the nature of the final gathering.

For the caustics photon map, I’ve used the technique mentioned by Keller and Wald in Efficient Importance Sampling Techniques for the Photon Map. All photons that have gone through a specular event before hitting a diffuse surface, are stored in the caustics map. All other photons are stored in the global photon map after being selected with a probability of 1/Q, with Q the caustics quality factor. The Q factor is an easy way to set the resolution of the caustics map. If you set it higher, it will contain more photons and deliver crispier caustics. There’s still some issues with the caustics map though. I need to add some filtering, and use the convex hull as an area estimate to get crispier caustics and prevent leaking.

To experiment with the caustics, I’ve added a dielectric Fresnel shader with proper reflection and refraction (see my article Reflections and Refractions in Ray Tracing), which is of course used for the yellow sphere. I’ve deployed a simple medium material system (volumetric shaders), so that I could attenuate the light going through the sphere using Beer’s law. The yellow colour is entirely due to this Beer medium, as the Fresnel shader is … well … colourless (greyscale).

For the blue sphere in the back, I’ve implemented the famous Ashikhmin & Shirley BRDF (An Anisotropic Phong BRDF Model and An Anisotropic Phong Light Reflection Model). This of course has nothing to do with caustics, but it’s a very cool shader nevertheless. Notice the slightly glossy reflection and the Fresnel behaviour at grazing angles. I do have problems for keeping the photons at constant powers though, the specular lobe bumps power up, but I’m not really sure if it can be avoided.

Caustics in the Cornell box

Where’s the road going from here? One thing that I certainly want to add to the photon mapper is importance driven photon shooting, so that we can go crazy with sky lights and windows … The other is some priority stack for medium materials, to solve the water-in-a-glass problem (more about that later). And while we’re at it, we should add more in- and outscattering to the medium materials so we can have fog =) I’m also trying to put one of the PHD-Motorsports cars in the Cornell box, but I seem to have some problems to smooth the mesh properly.

PS: we have reached revision 42 in the subversion repository. w00t! ;)

2 Responses to “caustics in the cornell box”

  1. Reedbeta Says:

    Last comment for today ;)

    Regarding the water-in-a-glass problem, something I’ve thought about is to forgo volumetric objects entirely, and just define things in terms of surfaces and interiors. Each surface would have a pointer to a pair of interiors, one on each side of it, so the raytracer could easily keep track of what kind of interior it’s in as it moves through surfaces, and perform scattering effects as necessary. This way the water in a glass would be modelled as 3 separate surfaces: the glass-air surface, glass-water surface, and air-water surface. Of course, you would also have to let the raytracer know in which medium the camera lies, so it could start the rays with the proper interior.

  2. bramz Says:

    The problem with that solution is that you need to … well … model it as three different surfaces. This is a bit of a burden on the artist. Plus you need to be carefull to avoid gaps. The priority stack is an idea of DirtyPunk that’s currently being used by OnoSendai in the Indigo Renderer. The idea is that you use only two closed surfaces: one that models the glass, and the other the body of water in the glass. But you do it so that the latter is a little bit too big so that the sides and bottom are actually inside the glass. Then you assign a lower priority to the water than to the glass (and an even lower priority to the air), so that the glass “pushes away” the water: when you intersect with the water, the intersection is only valid the current medium has a lower priority.

    Here’s the topic in the Indigo forum.

    I know of this trick quite some time now, but it’s still on the TODO list …