About Me

Hi. I'm Josh Ols. Lead Graphics Developer for RUST LTD.


View Joshua Ols's profile on LinkedIn


Entries in SSAO (2)



Now that I've got Radially Symmetric Reflection Maps (RSRMs) figured out, it's time to tackle the rest of my ambient lighting solution. So the next logical step for improving lighting quality is to introduce Ambient Occlusion (AO). As my plan is to go the route of deferred shading, the natural choice for getting the best visuals is Screen-Space Ambient Occlusion (SSAO).



My long-time readers might recall that I have touched on this topic before, getting acceptable results for the time. However, I recently came across a new implementation that is both cheaper and more visually pleasing than my previous choice. For implementation details, check out the gamedev.net article "A Simple and Practical Approach to SSAO".


Here you can see the results I got when I combined this technique with RSRMs. In each shot, the AO is correctly applied to just the ambient diffuse & specular contributions. The direct lighting is currently unshadowed, so it is not as good as it could be.



[RSRM, SSAO] ssao only [SSAO] ssao, old implementation

Figure 1. 1, New; 2, Old

(Model by Ben Mathis)



[RSRM, SSAO] Ambient diffuse w [RSRM, SSAO] Ambient diffuse wo [RSRM, SSAO] Ambient specular w [RSRM, SSAO] Ambient specular wo [RSRM, SSAO] composite w [RSRM, SSAO] composite wo

Figure 2. 1, Diffuse w; 2, wo; 3, Specular w; 4, wo; 5, Composite material w; 6, wo

(Model by Ben Mathis)


Future Plans:

As nice as SSAO can look, even the cheapest implementation can still be a performance hog even on newer hardware. So for older GPUs I will likely be using a textured AO fallback, with min blending to combine model and detail AO maps. It may not look as good, but AO in any form is still a huge step up from no AO at all.


Sorry for the delay folks. That "real life" thing has a habit of getting in the way of my leisure activities. :p


Screen-Space Ambient Occlusion

SSAO seems like a must these days, especially if you want a game that has fully dynamic content. The benefits to the overall look of the game may be subtle, but they are nonetheless substantial. So right from the start of my project, I have been determined to integrate this technology into my renderer.



My current test hardware is crappy, there is no denying that. My development platform is about six years old, and has an AGP GeForce 6800 GT GPU. Needless to say, this severely limited the variety of techniques I could try. Still, I didn't want technical limitations to cost me quality, and needed something that would provide such at a reasonable performance cost.

Keeping those restrictions in mind, here are the criteria I sought:

  • Normals influence occlusion
  • Handles self-occlusion
  • Eliminates "halos"
  • Looks decent without blurring
  • Doesn't use branching
  • Requires few samples

After much research and experimentaion, I settled on an approach developed by nullsquared (gamedev, ogre3d), which meets all my criteria beautifully. For the most part it follows the typical steps of any SSAO implementation, but differs in how it determines when a sample is occluded. Since I only vaguely understand how it works and don't care to explain it, I will refer you to read about his implementation.


Ogre3D forums: SSAO Compositor

Ogre3D forums: SSAO Demo + Source

Ogre3D forums: SSGI



For the test scene, the geometry was illuminated using one hemisphere light + six point lights. In order to get the best results, I do the ambient pass first, then apply SSAO to the light buffer via multiplicative blending. Then, I proceed to add the point lights on top of the ambient contributions. All calculations are handled in linear space, and receive color correction before being rendered to the back-buffer.

The nature of my deferred lighting renderer allows me to apply SSAO correctly to the ambient lighting. Most games would incorrectly apply it to the final rendered image as a post-process. While this can look good enough, it is not exactly correct since it affects all lighting (direct/indirect, diffuse/specular/reflection, etc).

So here are the results of this setup:

(SSAO) SSAO buffer (SSAO) SSAO & Ambient (SSAO) SSAO + ambient + point lights (SSAO) ambient + point lights (SSAO) difference

Figure 1. 1, SSAO; 2, SSAO & Ambient; 3, SSAO & lighting; 4, lighting; 5, difference



My tests showed that a scene of about 180,000 polygons rendered at 1280 x 720 ran at roughly 20fps, while the same scene rendered at 800x600 ran at 30fps. This was without any optimizations, such as using downsampled normals/depth and render targets for the SSAO. Plus, I haven't added a smart blur to the SSAO contributions yet, partly because the result look good enough as is.

In the future, I will be look at options for reducing the cost, such as using even fewer samples, and/or downsampled buffers. This will necessitate blurring, in order to cover up the pixelation of the occlusion, as well as good upsampling. These are areas which can also stand to benefit from optimizations tricks. ;)