Today I fixed the last parts to get the indirect illumination rendering going properly, and I even made a video of it! The times when it goes dark is when the light map is reset and rebuilt (I do this for demonstrational purposes) from scratch. As you may notice, the color bleeding looks a bit strange from the yellow, red and orange cubes to the left. This is because the cube sides are not solid and become invisible when rendered from the lights perspective, which makes these cubes cast indirect illumination onto the wall. The frame rate of this application is around 1500 on my ATI 5770, so it’s pretty fast (still debug mode). The only other light source is from the sky, using the sky occlusion map described in the last post; direct lighting not included in this scene. The ugly stuff in the top of the screen is because I don’t clear the back buffer properly each frame. Oh, and this lighting is not physically based, and in the video the indirect illumination is probably far too strong.
Dynamic objects
I haven’t yet mentioned anything about how I plan on handling dynamic objects. Dynamic objects are slightly problematic as they tend to move and ruin any nice acceleration structure that was built. Dynamic objects should be able to illuminate nearby objects with indirect illumination and thus be able to “emit” color bleeding. I don’t think that this will be very problematic, indirect illumination from dynamic objects can use a dedicated light maps that is updated more often than the main light map. To ray trace the light in this low resolution light map will also be quicker as the rays will be a lot fewer compared to the static scene due to (most likely) fewer and smaller objects.
Then there is being affected by indirect illumination from other objects. This one will be a little bit trickier. I’m currently leaning towards using light probes placed all over the scene, and dynamic objects then use values that are interpolated between the closest light probes. These light probes will get their values from when I ray trace indirect illumination for the static geometry.
Finally, there is (large-scale) ambient occlusion. Receiving occlusion from static objects will be handled by the light probes. However, occluding static geometry is harder and I haven’t decided how I’ll solve this yet. At the moment I’m leaning between two alternatives. The first alternative is that I’ll solve the problem by having sky visibility maps for static geometry, but for every pixel I just project the bounding spheres/boxes of the significant occluders onto the pixels hemisphere and approximate the occlusion that way. The second alternative is that I don’t solve it at all and instead implement some variant of SSAO, as dynamic objects mostly are quite small and don’t provide much occlusion anyway.
I’m not sure what I’ll work on next, a proper scene to test the performance (as in visual quality and speed) of this technique would be nice. However, since I have some additional requirements about geometry and UV-mapping this will be slightly problematic. I could implement some nice shadowing algorithm and see the result with direct illumination as well, and tweak some parameters to fix the strength of the indirect light.
Just an additional note, I’m fully aware that measuring performance in terms of FPS is rather useless. However, my graphics card has suddenly forgotten that is has performance timers, so I can’t do any profiling with it. Not that the performance numbers are realistic anyway, since the scene I’m not using isn’t exactly the most commonly used one in games.