A demonstration of volume-intersect ambient occlusion

Volume-intersect Ambient Occlusion

While creating a new environment for Impaler, I devised a new method to approximate ambient occlusion on a grid-based map. The result is computationally cheap, pleasing to the eye, and builds on ideas from my last post. It works by comparing the volume of a cube with the volume shared between the cube and the environment (i.e., their intersection). The ratio between the two volumes is then used as an occlusion factor.

Quick refresher: Ambient occlusion is a technique for applying self-shadowing to environments and objects.


How It Works

Volume-intersect AO calculates how much unobstructed volume exists in front of a given point. Points with nearby geometry will have less obstruction-free volume, making them more occluded.

Pseudocode

  • place an AABB (axis-aligned bounding box) at the world position of the current fragment
  • offset the AABB in the direction of the surface normal by 1/2 its size
  • sum the volume of intersections between the AABB and nearby world geometry
  • calculate the ratio between the total intersect volume and the sample AABB volume
  • repeat N times - each with a smaller sample AABB
  • [OPTIMIZATION] return when the intersect volume is zero (subsequent samples will also be 0)
  • sum & weight results (high values are more heavily occluded)

Sampling Visualized

The white dot is the current fragment and the boxes are the sample volumes. Notice how the larger samples have significant intersections with the environment, shown as red areas. If the fragment was closer to the corner, there would be more red areas resulting in a higher value.

Sampling visualized in 2D


Performance & Limitations

Similar to the approach in the previous post, this technique involves sharing environment data with the fragment shader. This will limit its use to simple environments like those in Impaler. It may also be possible to adapt this approach to work with spheres or voxels. Being limited to AABBs is the biggest limitation in its current form.

The performance is good for simple scenes

  • it requires no texture reads
  • looks good with as few as 5 samples
  • AABB <> AABB intersection calculations are cheap
  • the early return optimization makes un-occluded fragments almost free

Shadertoy Example

See the real-time demo and source here on Shadertoy.

Screenshot with colored tiles Screenshot with white tiles


Using It In a Game?

The Impaler Gold re-release implements Volume-intersect AO in the new arena. Check it out below.