I OMGed. I came. I completely blew my own mind. I AM AWESOME.
I JUST IMPLEMENTED THIS:
http://img706.imageshack.us/img706/7858/godrays.png
That’s right! I just implemented real time ACCURATE god rays!!!
I was reading around on the internet about this effect, and many people seem to use a really bad approximation method using a radial blur. It looks good in the most important cases (for example in Crysis when you’re looking at the sun through palm leaves), but completely fails for overlapping geometry. Reading up on the technique I realized they were doing LOTS of samples to do the radial blur. So I just thought “why not use those samples for ray tracing instead?”. So I did. The image above is generated in realtime, using 64 samples, but 32 samples has only very limited banding and is probably the best option for performance.
This is a post processing algorithm, but it doesn’t run completely independent of the scene performance-wise. First I create a shadow map for the scene. Then I render the scene normally with lighting and shadows. Finally I raytrace through the shadow map to find out how much of this ray is shadowed. Only about 32 samples is needed to reduce banding to acceptable levels. Comparing to the 50+ samples used in the radial blur of the fake algorithm, this performs similarly. The advantages are correct lighting for overlapping light shafts/shadow shafts, it works independent of the screen orientation and also even for objects that aren’t on screen (VERY different results from the fake algorithm). It works with any shadow map! It looks AWESOME!
The FPS is kind of low, only about 40 FPS at 1080p on my GTX 460M. However, considering the blurry nature of the effect and the built-in “anti-aliasing”, it should be completely indistinguishable to render it at half resolution or even 1/4th or less. Increasing the samples and reducing resolution should together with bilinear interpolation reduce banding and increase performance. Shadow map resolution also plays a small role.
Sorry for my nerdgasm, but this is without a doubt THE most awesome thing I’ve ever programmed. I just HAD to make a dedicated thread for it!