2.29
Filter: Screen Space Ambient Occlusion

- 2.29.1. Overview
- 2.29.2. Ambient Occlusion Buffer
- 2.29.3. Algorithm
- 2.29.4. Noise Texture
- 2.29.5. Sample Kernel
- 2.29.6. Halo Removal
- 2.29.7. Performance
- 2.29.8. Types
- 2.29.9. Shaders

2.29.1
Overview
1
Screen space ambient occlusion is, unsurprisingly, an approximate algorithm for calculating ambient occlusion in screen space. Informally, ambient occlusion is a measure of how exposed a given point is to the environment's ambient light. The r2 package does not directly support ambient lighting, so instead the diffuse light term is typically modulated by an ambient occlusion term [27] to produce the same overall effect.
2.29.1.2 SSAO
2.29.2
Ambient Occlusion Buffer
1
An ambient occlusion buffer is a render target in which an occlusion term is stored. In the r2 package, ambient occlusion buffers are simple single-channel 8-bit images, where 0 means fully occluded and 1 means not occluded.
2.29.3
Algorithm
1
The algorithm works by consuming the depth and normal values from populated geometry buffer. For the sake of simplicity, the algorithm will be described as if the ambient occlusion buffer that will contain the calculated occlusion terms will be the same size as the geometry buffer. This is not necessarily the case in practice, for performance reasons. For each pixel at (x, y) in the geometry buffer, the eye space Z value z is reconstructed for the pixel, and the eye space normal vector n is sampled at the same location.
2
Then, a sampling hemisphere is placed on the surface at z, oriented along n. A list of points, known as the sample kernel, are used to sample from random positions that fall inside the hemisphere. If a sample point appears to be inside the scene geometry, then the scene geometry is occluding that point.
2.29.3.3 Sampling Hemispheres
4
Informally, the algorithm for a point at (x, y):
2.29.3.5 Algorithm

1. Reconstruct the eye space position e of the screen space position (x, y).
2. Sample the normal vector n at (x, y).
3. Peturb the normal vector n using values sampled from a random noise texture that is tiled across the screen.
4. Produce a normal matrix from n that will transform the inherently tangent space sampling kernel vector to eye space. The peturbed normal vector has the effect of rotating the sampling hemisphere.
5. For a sampling kernel k of m points, of radius r, for each i | 0 <= i < m:
   1. Calculate the eye space position q of the sampling point k[i]. This is calculated as q = e + (k[i] * r).
   2. Project q to screen space, use it to sample the depth buffer, and reconstruct the resulting eye space Z value sz. The value sz then represents the eye space Z value of the closest position of the surface in the geometry buffer to q.
   3. If abs (e.z - sz) > r then the point is automatically assumed not to be occluded. See halo removal for details.
   4. If sz >= e.z, then it means that the sampling point in the hemisphere has ended up underneath the rendered surface and is therefore being occluded by it.
6. Calculate the final occlusion value o by summing the occlusion values of each sample point, where 1.0 means the point was occluded, and 0.0 means that it was not. Return 1.0 - (o / m).

2.29.4
Noise Texture
1
The noise texture used by the algorithm is a simple RGB texture with each texel being given by the expression normalize ((random() * 2.0) - 1.0, (random() * 2.0) - 1.0, 0.0). The sampling kernel used by the algorithm is conceptually oriented along the tangent space Z axis, and therefore each texel in the noise texture effectively represents a rotation around the Z axis.
2
In the implementation of the algorithm, the texture is simply tiled across the screen and sampled using the current screen space coordinates.
2.29.5
Sample Kernel
1
A sample kernel is a fixed-size list of random sampling points, arranged in a hemispherical pattern. For better visual results, the random points are not evenly distributed within the hemisphere but are instead clustered more densely nearer the origin.
2.29.5.2 Point Distribution
3
By using a distribution of sample points nearer the origin, samples closer to the origin have the effect of occluding more than points that are further away.
2.29.6
Halo Removal
1
A common problem with SSAO implementations is haloing. In practical terms, this is an issue caused by two objects being very close when considered in screen space, but that were actually far apart when considered in eye space.
2.29.6.2 Halo Artifacts
3
The simple solution to this problem is to ignore any surface points that are at a distance greater than the sampling radius from the origin. In the actual implementation, a simple comparison of the eye-space Z values is used.
2.29.7
Performance
1
The SSAO algorithm is extremely expensive; by far the most expensive algorithm implemented in the r2 package. The package provides numerous means to control the performance of the algorithm.
2
For a kernel of size n, an occlusion map of size w * h will incur at least w * h * n texture reads when sampling from the geometry buffer to calculate the occlusion term. Therefore, reducing the resolution of the ambient occlusion buffer is an effective way to improve the performance of the algorithm at a noticeable reduction in visual quality. The r2 package does not provide any specific support for this; the programmer simply needs to allocate a smaller ambient occlusion buffer. For the same reason, using a smaller kernel (a smaller value of n) will also improve performance but reduce visual quality.
3
To reduce high frequency noise introduced by the random sampling pattern used, a bilateral blur filter is often used. In the r2 package, the blur is separate from the SSAO effect and can therefore be omitted to improve performance at the cost of producing a noisier image:
2.29.7.4 SSAO (Without blur)
5
The image displayed at the start of this section uses an ambient occlusion buffer that is exactly half the size of the screen, a kernel of size 64, and a maximum sampling distance of 0.25 eye-space units. A single bilateral blur pass was used.
2.29.8
Types
1
In the r2 package, the SSAO effect is provided by the R2FilterSSAO type.
2
Occlusion maps can be conveniently applied to light maps with the R2FilterOcclusionApplicator filter.
3
The provided implementation of the sampling kernel is given by the R2SSAOKernel type.
4
The provided implementation of the noise texture is given by the R2SSAONoiseTexture type.
2.29.9
Shaders
1
The shader implementation of the SSAO algorithm is the R2SSAO shader.

[27]
The r2 package provides convenient methods to apply ambient occlusion to lighting, but does not require the programmer to use any particular method.