<p>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.</p>

<p>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.</p>

<p>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.</p>

CC BY-SA 3.0
2015-08-31T21:43:48.277Z
2015-08-31T23:07:44.043Z
2015-08-31T23:07:44.043Z
Noah Witherspoon
<p>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&mdash;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.</p>

<p><a href="https://i.sstatic.net/1JZDi.jpg" rel="noreferrer"><img src="https://i.sstatic.net/1JZDi.jpg" alt="photo demonstrating AO-like effect in the corner of a room"></a></p>

<p>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.</p>

<p>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.</p>

<p><a href="https://i.sstatic.net/qFOoX.png" rel="noreferrer"><img src="https://i.sstatic.net/qFOoX.png" alt="diagram of how depth buffer represents geometry, from Bavoil and Sainz (2008)"></a></p>

<p>This diagram, from <a href="http://developer.download.nvidia.com/presentations/2008/SIGGRAPH/HBAO_SIG08b.pdf" rel="noreferrer">Bavoil and Sainz (2008)</a>, 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.</p>

<p>The formula that the depth values go into is called the "kernel" by analogy with <a href="https://en.wikipedia.org/wiki/Kernel_%28image_processing%29" rel="noreferrer">filter kernels</a> 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.</p>

CC BY-SA 3.0
2016-03-12T00:10:18.600Z
2016-03-12T00:10:18.600Z
Nathan Reed
<p>I do not understand the <a href="https://en.wikipedia.org/wiki/Screen_space_ambient_occlusion#Implementation">explanation</a> from wikipedia.</p>

<blockquote>
  <p>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.</p>
</blockquote>

<p>How can depth values of surrounding pixels tell you something about occlusion? <strong>Occlusion</strong>, 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 <strong>surrounding</strong> pixels? I mean you can see those pixels, so there is no occlusion. Maybe I understood occlusion wrong.</p>

<p>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?</p>

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

CC BY-SA 3.0
2015-08-31T14:21:11.977Z
think about it this way: a deep crease will have shadows in it.
Alan Wolfe
CC BY-SA 3.0
2015-08-31T20:15:57.220Z
The key thing to understand here is that we are trying to calculate occlusion of the ambient light, not occlusion from view.
trichoplax is on Codidact now
<algorithm><lighting><shading>
How is screen space ambient occlusion implemented?
Joey
# How is screen space ambient occlusion implemented?

(Asked by: username_0 on 2015-08-31)

I do not understand the [explanation](https://en.wikipedia.org/wiki/Screen_space_ambient_occlusion#Implementation) 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?

**Tags:** algorithm, lighting, shading

> **Comments:**
> **username_1**: think about it this way: a deep crease will have shadows in it.  
> **username_2**: The key thing to understand here is that we are trying to calculate occlusion of the ambient light, not occlusion from view.  

---

## 2 answers

### Answer by username_4 on 2016-03-12. Score: 6 | Accepted answer

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.

[![photo demonstrating AO-like effect in the corner of a room](https://i.sstatic.net/1JZDi.jpg)](https://i.sstatic.net/1JZDi.jpg)

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.

[![diagram of how depth buffer represents geometry, from Bavoil and Sainz (2008)](https://i.sstatic.net/qFOoX.png)](https://i.sstatic.net/qFOoX.png)

This diagram, from [Bavoil and Sainz (2008)](http://developer.download.nvidia.com/presentations/2008/SIGGRAPH/HBAO_SIG08b.pdf), 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](https://en.wikipedia.org/wiki/Kernel_%28image_processing%29) 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.


---

### Answer by username_3 on 2015-08-31. Score: 6

As username_1 and username_2 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.


---

