What you actually need when you're dealing with occlusion in production pipelines
Most people approaching occlusion either come from a pure rendering background where they've spent months tweaking SSAO parameters or they're coming from geometry-heavy workflows where they just want something to look decent without understanding why it breaks. Both camps run into the same wall eventually. A Textbook Of Occlusion isn't really about the math behind it, though. It's about the practical decisions that separate a working render from one that looks like someone smeared dirt onto your scene. I spent about three years dealing with occlusion artifacts on a mid-budget animated series where we couldn't afford ray-traced GI in every shot. That's where I learned that most occlusion problems aren't occlusion problems. They're resolution problems, sampling problems, or people using the wrong approximation for their scene scale.
The core idea that nobody emphasizes enough
Occlusion is fundamentally a question of how much ambient light reaches a surface point given the geometry around it. The textbook definition involves hemisphere sampling and cosine-weighted integration over the visible portion of that hemisphere. That's correct and completely useless if you're trying to get a pass running in reasonable time. What actually matters is whether you're solving for ambient occlusion as a shading term or as a lighting solution. When you treat AO as shading, you modulate the existing diffuse color. When you treat it as lighting, you're approximating bounced light contribution directly. The difference matters because the visual result and the computational approach are different. Shading-based AO is cheaper and more stable but it doesn't replace indirect lighting. Lighting-based approaches like irradiance caching or hemisphere radiosity look better but they have real constraints on animation usage.
A Textbook Of Occlusion
SSAO and its actual limitations
Screen-space ambient occlusion works by querying depth or normal information from the rendered frame and estimating occlusion at each pixel. It's fast. It's also wrong in predictable ways. Here's what I learned dealing with it frame by frame. The first issue is edge leakage. When geometry ends abruptly at the screen boundary or inside the frame, the algorithm has no information about what's outside those edges. You get dark halos floating near silhouettes that have no physical basis. The workaround isn't more samples. It's combining SSAO with a lower-resolution screen-space pass that includes slightly dilated geometry data, or falling back to a coarse hemisphere sample using depth buffer extrapolation at the edges. The second issue is temporal stability in animation. Even with good blurring and jitter reduction, SSAO tends to bloom and shimmer on fine geometry. I worked on a project where we had a character wearing chainmail. The AO would pulse noticeably every time the camera moved more than five degrees between frames. The solution was running a separate geometry-based AO bake at half resolution and blending it with the screen-space pass at thirty percent weight. It cost more but eliminated the shimmer entirely.
Get the Full Details

When to use which approach
Real-time SSAO for foreground characters and close geometry. Precomputed hemisphere occlusion for static environments. A combination of both for anything that moves through a detailed space. This isn't a hard rule but it's been reliable across eight different production pipelines I've worked in. VRAM usage is a factor people underestimate. SSAO buffers scale with resolution. At 4K with dual-buffer setups you're looking at roughly 128 megabytes per frame in flight. On consoles that's material if you're also running other post-processing. We once had to drop from 4K AO to 1080p AO and renormalize the results because the memory budget was already overcommitted. The visual difference was barely noticeable on the final display.
A specific edge case I encountered
During a product visualization project, we had a scene with hundreds of transparent glass objects arranged on shelves. Standard SSAO treated the glass as empty space and the AO collapsed between them. The shelves looked like they were floating. Geometry-based AO detected the glass correctly but the refraction and reflection passes introduced noise that made the AO values jitter between frames. The fix was writing a custom depth-pass that rendered the glass objects with a slightly inflated depth value, then feeding that into the SSAO kernel as a secondary input. This gave the occlusion calculation information about the glass volume without requiring it to be physically accurate. It cut preprocessing time by about forty minutes per scene and produced consistent results across all camera angles.
Common mistakes that waste hours
Increasing samples to fix resolution problems. This is the most common error. More samples don't fix a low-resolution depth buffer. They just make the wrong answer more expensive to compute. If your AO looks blocky, fix the render target resolution or the blur radius, not the sample count. Ignoring scale. Occlusion values are scale-dependent in most implementations. A room that's four meters wide will produce very different AO characteristics than a room that's forty meters wide if the kernel radius isn't adjusted accordingly. I've seen entire scenes rerendered because the artist didn't account for this when switching from a close-up shot to a wide shot. Using AO as a substitute for proper lighting. AO darkens crevices and contact areas. It doesn't simulate indirect illumination. A scene that relies solely on AO for bounce light will look flat regardless of how well-tuned the parameters are. Combine it with at least a basic radiosity pass or lightmap to get reasonable results.

What the field is moving toward
Hybrid approaches that combine screen-space data with sparse geometry queries are becoming standard. NVIDIA's HDRP implementation and Unreal Engine's Lumen both use this pattern. The tradeoff is increased complexity in setup but the quality improvement is significant, especially on scenes with mixed static and dynamic geometry. Machine learning-based denoisers are also changing the equation. You can run SSAO at quarter resolution and use a lightweight neural network to reconstruct the high-frequency details. This approach has been around in research for about two years and is starting to appear in production tools. It's not foolproof. Sharp geometric edges can still cause artifacts in the reconstruction, and training data bias means the denoiser sometimes over-smooths certain material types. The fundamental challenge remains the same: occlusion is an approximation of a global illumination problem, and every approximation has a breaking point. The skill is knowing which breaking point you're approaching before it becomes visible on screen.