# How is screen space ambient occlusion implemented?

I do not understand the explanation from wikipedia.

For every pixel on the screen, the pixel shader samples the depth values around the current pixel and tries to compute the amount of occlusion from each of the sampled points.

How can depth values of surrounding pixels tell you something about occlusion? Occlusion, as I understand, happens when an object A stands in front of another object B, so you cannot see the object B. But why would you now look at the depth pixels of surrounding pixels? I mean you can see those pixels, so there is no occlusion. Maybe I understood occlusion wrong.

And what I also did not understand is the term kernel in some other tutorials. What is a kernel and why would you use it for ssao?

Could someone make a detailed explanation of the algorithm, with regard to my questions?

• think about it this way: a deep crease will have shadows in it. Aug 31, 2015 at 14:21
• The key thing to understand here is that we are trying to calculate occlusion of the ambient light, not occlusion from view. Aug 31, 2015 at 20:15

The motivation behind ambient occlusion (AO) in general is to approximate the way crevices and corners are often shadowed, because less indirect light bounces into them. An example from a photo of my office—note the darkening along the edges where walls and ceiling meet. The room is lit only by the light coming in through the window and bouncing around.

To accurately simulate this phenomenon, offline renderers use techniques like path tracing and photon mapping. For real-time purposes, we either precalculate it offline, or we approximate it somehow.

Screen-space ambient occlusion (SSAO) is based on the observation that you can detect corners and crevices by looking at the depth buffer (and possibly also the normal vectors) of a rendered image, and so you can calculate approximate AO as a post-pass. The depth buffer is a coarse representation of the geometry in the scene, so by sampling depth buffer values in the neighborhood of a target pixel, you can get an idea of the shape of the surrounding geometry, and make a guess how darkened by AO it should be.

This diagram, from Bavoil and Sainz (2008), shows how depth buffer values, interpreted as a heightfield of sorts, represent a discretized version of some geometry. In calculating SSAO for the center pixel, you'd look at the depth values of the surrounding pixels and plug them into some formula, designed to produce a darker value when the geometry is more concave (like that in the diagram), and a lighter value when the geometry is flat or convex.

The formula that the depth values go into is called the "kernel" by analogy with filter kernels used for blurs, edge detection and suchlike. However, SSAO is more complicated than just a linear convolution of the depth values. The devil is in the details. The distribution of samples, and the formula processing them to generate the occlusion value, has been the subject of much research over the last decade, trying to improve the realism and reduce artifacts while maintaining good performance.

As Alan and trichoplax mention in the comments, the effect that ambient occlusion simulates is not the occlusion of a surface from the camera but the surface’s occlusion from its surroundings.

Think of it this way: say you have even illumination coming from every direction, so that the total incoming light at any point sums up to a value of 1. If you place a flat plane in that environment and look at one side of it, that side is going to receive 50% of that illumination, or 0.5, because the other half is blocked by the plane itself. In other words, any point on the plane’s surface can only “see” the light coming from half of the environment, so it’s half as brightly illuminated. If you fold that plane towards your viewpoint (a “valley” fold), then you decrease the incoming illumination to that side of the plane further, to some value below 0.5, because, again, each point on the plane “sees” a bit less of the light coming from the surroundings.

Screen-space ambient occlusion works more or less by looking for these “folds”—areas where the depth changes sharply, as defined by comparing the depths of neighboring pixels—and darkening them to simulate the decreased illumination from the points’ environment.