Real-Time Caustics Using Screen Space Directional Occlusion

Damon Blanchette
Master's Thesis
Professor Emmanuel Agu
Worcester Polytechnic Institute Department of Computer Science

Previous Page!

September 21, 2011
Okay even longer with no update this time! I have completed an unbelievable amount of work since July 3rd, so hopefully I can summarize it accurately here. Let's see, last update I just converted everything to run in Windows on my newer laptop, and I'd start implementing Adaptive Caustic Maps. It turned out over the course of about a month that ACMs would never work on that laptop because it has an ATI video card. After a couple weeks of troubleshooting, I found out that one very important part of an ACM geometry shader (that creates the correct textures and speeds things up) requires a gl_Layer call, which is broken on ATI cards - even the brand new and awesome one in my laptop. So I then had to recreate everything yet again on my old laptop, which happened to have a nVidia card in it, albeit an old slower one.

Getting everything going on the nVidia laptop took another bunch of days, but once I had it running there was a nice change - ACMs actually worked! Here are the first screens from that:

ss55    screenshot56

The bunny looks weird because that was before I fixed the deferred refraction shader, and the dragon shows things looking good. At this point my adviser showed me a brand new nVidia card (an amazing GTX480) in his office and offered it to me for use in my thesis. I had no computer to put it in, so I purchased a bare-bones tower (that cost less than just the video card!) and got it up and running. I then transferred my thesis code yet again and for the third time to this new computer, updating it to run in VC++ 2010 in the process. The results were immediately apparent - I had an orders of magnitude framerate increase, from 1-2 fps on that old laptop to around 20 fps!

In fact the results were so much better that I took a video capture of the program running (note the caustics are brighter than they should be - I fixed that after this video was captured):

Next step, with ACMs working, was to integrate SSDO code back into my program. After about a week of preliminary work, I got SSDO running again with ACMs in a couple long late nights of feverish coding (not sure where the energy came from!), and here are those screenshots, pre-nice-looking-blur:

ss58    screenshot59

After getting the blur shader from SSDOs working and fiddling with a bunch of variables including brightness of the caustics, here are some current screenshots:

ss61    screenshot62

Not absolutely perfect, but pretty nice I'd say! And for your viewing pleasure, a video of it actually running. Here the speed is about 15 fps:

The question then became, "where do I go from here?" and "what amazing publishable and cool feature will I implement?" The last week or two has been spent thinking about that, researching, and reading papers. One possibility I came up with was reflective caustics, which is something that ACMs do not handle, as can be seen in the following screenshot (with a reference LuxRender image I rendered in 15 minutes next to it showing what should be happening):

ss63    reflective caustics

Unfortunately this effect would probably be too simple and small of an update to be good enough of an avenue to go into, plus it's been done before by Shah and Pattanaik (way back in 2005!). One thing that has piqued my interest actually for quite a while now is spectral rendering. In this method of rendering, the wavelength of light is taken into account. In essence, when you render a prism with white light going through it, you end up with a rainbow on the other side. It also will show correct colors in gemstones such as diamonds, where the refracted light is broken up into individual components. Here's another image I created with Blender and LuxRender (which handles spectral rendering), rendered in about an hour:

spectral rendering

Notice the colors near the edges of the diamond, even though the scene is only bathed in white light and the diamond is totally clear. A small somewhat visible rainbow can also be seen to the right of the base.

After quite a lot of thought and research, plus laying in bed at night thinking about gemstones and rainbows way too much, I've decided to implement dispersive refraction in my thesis as of today. Yes, the Shah and Pattanaik page I linked to above shows it in a small way, and from what I read in their paper all they did was give a different index of refraction for each color. They did not implement physically accurate spectral rendering per se, though I may contact them to find out exactly what they did. Their paper focuses on just caustics mapping, not on dispersive refraction.

So, in a couple months I hope to have a prism in my scene with light shining through it and a physically accurate rainbow on the other side (of course with some great global illumination and caustics as well!). Updates will hopefully be coming more often too!