ComfyUI Node

AO Approximator

Ambient occlusion without a 3D scene

By amtarr·Created 9 months ago·Updated 4 months ago· 58
AO Approximator
  • height
  • normal
  • ao
radius8
strength1.00
samples16
contrast1.00
use_normaltrue

Ambient occlusion - the darkening in corners, crevices, and anywhere geometry traps light - is one of those maps that's easy to want and annoying to get. Real AO is baked by ray-tracing a 3D model. If all you have is a flat texture with a height map, you can't bake. AO Approximator is the cheat: it fakes AO from your height and normal maps in pure torch, no 3D scene required.

It's not a substitute for a proper engine bake on a hero asset - nobody's pretending a 2D approximation beats real geometry. But for game textures, quick materials, or when you need a roughness/AO set without opening Blender, it produces a perfectly serviceable occlusion map.

How it works

The core algorithm is a height-sampling approximation. It picks samples (default 16) directions around each pixel, steps radius pixels out in each direction, and compares the sampled height against the center. Wherever the neighbor is higher than the center, that direction is occluded. More directions and a larger radius both mean softer, broader occlusion; fewer samples are faster but can leave visible artifacts. The collected occlusion is scaled by strength and pushed through a contrast pass.

Then the normal map refines it. If you connect a normal and keep use_normal on, the node biases the AO with surface orientation - upward-facing surfaces get less occlusion, steeper faces get more, which is the part that makes the result read as 3D rather than as a blurry copy of the height map.

The inputs

  • radius (1–64, default 8) - sample distance in pixels. 8–16 is the typical zone.
  • strength (0–3, default 1) - overall AO intensity.
  • samples (4–64, default 16) - quality vs. speed. 16 is a good default; drop to 8 for drafts.
  • contrast (0–3, default 1) - punch up or soften the result.
  • use_normal (default on) - use the normal map for the orientation bias.
  • height and normal - both optional, but the magic happens when you feed both. Height alone works; normal alone produces a cruder orientation-based AO.

Output: ao - a grayscale IMAGE where white is fully lit and black is fully occluded (the standard convention).

Two things to know

The pack's README explicitly recommends feeding both height and normal at 24–32 samples for the best quality, and the cost is worth it on a 2K texture. And if you feed neither height nor normal, the node doesn't error - it returns a flat 0.7 gray with a warning. That's the "I forgot to connect anything" failure mode; it'll silently pass a featureless map down the graph, so check your wires if your AO suddenly looks like a blank fill.

Installation

Part of amtarr/ComfyUI-TextureAlchemy, under Add Node → Texture Alchemist → Maps. Install via ComfyUI Manager (search "TextureAlchemy") or:

cd ComfyUI/custom_nodes
git clone https://github.com/amtarr/ComfyUI-TextureAlchemy

Restart ComfyUI. No dependencies - it's torch math over the maps you already have.

CategoryTexture Alchemist/Maps

Inputs (7)

NameTypeDefaultDescription
radiusINT81–64Sampling radius in pixels (larger = broader occlusion)
strengthFLOAT1.000–3AO intensity multiplier
samplesINT164–64Number of sampling directions (more = better quality, slower)
contrastFLOAT1.000–3Contrast adjustment for AO
use_normalBOOLEANtrueUse normal map to improve AO quality (if provided)
heightoptIMAGE
normaloptIMAGE

Outputs (1)

NameTypeDescription
aoIMAGE