2.28. Filter: Fog | 2. Design And Implementation | 2.30. Filter: Emission |
Previous | Up | Next |
Filter: Screen Space Ambient Occlusion
Overview
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 to produce the same overall effect.
Ambient Occlusion Buffer
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.
Algorithm
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.
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.
Informally, the algorithm for a point at (x, y):
Noise Texture
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.
In the implementation of the algorithm, the texture is simply tiled across the screen and sampled using the current screen space coordinates.
Sample Kernel
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.
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.
Halo Removal
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.
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.
Performance
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.
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.
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:
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.
Types
In the
r2 package, the SSAO effect is provided by the
R2FilterSSAO type.
The provided implementation of the sampling kernel is given by the
R2SSAOKernel type.
Shaders
The shader implementation of the SSAO algorithm is the
R2SSAO shader.
Previous | Up | Next |
2.28. Filter: Fog | 2. Design And Implementation | 2.30. Filter: Emission |