When we started working on Temporality one thing was very clear to us, to make a good looking indiegame on a shoestring budget we needed a good lighting solution that would take our simple models and make them look the best way we can. So we spent a lot of time on our light solution and we felt that a really solid SSAO solution was an important part of this. However with the limited bandwidth of the XBOX360 the traditional SSAO techniques wouldn’t work. We did some experimentation with low quality approximations like Volumetric Obscurance(crysis 2 used this on console). But we felt we needed something of a higher quality.
Here is an example of what our original implementation could achieve on the left side there is no SSAO and on the right side we added it.
The big issue with SSAO is that it samples the depth buffer to determine if a sample lies in front or behind the current depth buffer value. On the 360 4 samples are around the maximum that it can handle decently. This is what Volumetric Obscurance uses. The thing is that with 4 samples you can detect cracks but you really don’t have enough information to detect the longer ranging effects of the AO, so we knew we needed more samples. The first thing we did was to remember that since the camera doesn’t move around to different parts of the map every frame but are in the same are the same pixels on the screen will be visible during a large number of frames. Sure the pixel might move but it will still be the same place in the world with the same light information.
This idea is called Temporal Coherence and can be used to save time on any kind of calculations like shadows and so on. You just detect if the pixel has been calculated the frame before and reuse the value. Our solution however is a bit different. We want to use the Temporal Coherence to add new calculations for every frame that we combines with the old ones to create a more accurate view. We basically save values through the last 16 frames which gives us 16*4 = 64 Samples per pixel which is pretty nice since most ultra modes uses only 32.
Due to performance reasons SSAO are normally performed in a lower resolution and then blurred so that you won’t notice the pixels. This is a good optimization if you do it in 1/4 of the resolution you get to do it at 1/4 of the cost. And the SSAO needs a blur anyway due to the low number of samples. We discovered that with our 64 effective samples we really didn’t need that strong a blur which allowed us to drop resolution one step more to 1/16 of the resolution which made it possibly for us to also add in Screen Space Light bounces too and still keep it running on the 360.
However one problem of SSAO is that it only catches small scale obscurance and can’t really consider the larger forms and distant light obsurance and we felt we needed to fix this too. Our solution is to use multiple resolutions. We resolve SSAO at 1/16 1/64 and 1/256 resolution (which is 1/4 1/16 and 1/64 resolution around either axis) (this was before the paper was published to be honest I still haven’t had time to read it to compare). But due to the low resolution we got a lot of noise. However thankfully Temporal Coherence came to the rescue again. Due to the low resolution we could increase the amount of samples to 16 and 32 which gives us 256 and 512 real samples. Combined with a liberal blur(which we can do since we have high res data from the other passes) this allowed us to capture even distant effects of obscurance.
Last week we decided to revisit the SSAO due to the game being a PC centric title, what we realized is that while we could gain some wins with increasing sample count the solution we had in place did a good job for what it was meant to do. In fact in the end we just bumped the samples and the resolution. In Ultra mode we now get 256 Effective samples per pixels which gives an ultra smooth SSAO almost without any blur. And after careful bench marking we decided to retain this also for the very High mode but at the old resolution. While doing this we also did some extra parameters tweaking to give the SSAO just a little bit more umph.