Nodes/ComfyUI Minecraft PBR/Minecraft PBR - Derive AO + Height
ComfyUI Node

Minecraft PBR - Derive AO + Height

Your normal map hides two extra maps — this node digs them out

By jasonjgardner·Created 3 months ago·Updated 3 months ago· 0
Minecraft PBR - Derive AO + Height
  • normal
  • height_mask
  • ao
  • height
seamlessfalse
ao_strength2.0
ao_blur5
height_intensity1.00
height_min0.25
height_inverttrue

A material estimator gives you four maps, but two of them - ambient occlusion and parallax height - usually aren't among them. Minecraft PBR - Derive AO + Height manufactures both from a single normal map, and it's the same math the labPBR packer runs internally when you leave derive_ao_height on. The point of the standalone node is control: you get to preview and tune the AO and height before they get baked into the _n texture, or feed the outputs somewhere else entirely.

How it works

  • AO comes from the divergence of the tangent-space normal field - basically how much the normals splay apart, which is positive in crevices and negative on bumps. A Sobel pass plus a Gaussian blur turns that into an occlusion value (1 = fully unoccluded). ao_strength (default 2) controls how deep the effect bites; ao_blur (default 5) smooths the result.
  • Height is reconstructed by Frankot–Chellappa integration: the normal's X/Y gradients get integrated in frequency space with an FFT into a height field, then remapped into [height_min, 1]. height_min defaults to 0.25 - the author's deliberate Minecraft choice, since 0.25 = 25% block depth for parallax occlusion mapping. height_invert (default on) flips the direction so bumps rise instead of sink.
  • seamless (default off) mirrors the gradients into a 2×2 tile before integrating, so a tileable texture comes back without a seam at the edges. For game textures, this is the switch you'll almost always want.

Outputs are two MASKs, ao and height, which wire straight into the packer's optional ao / height inputs as overrides.

Inputs that matter

Only a handful matter day to day: normal (the only required input), seamless, ao_strength, ao_blur, height_min (leave at 0.25 for Minecraft), height_invert, plus the optional height_mask - where the mask is 1, height is flattened to height_min, handy for carving out flat spots like table tops or steps.

Install

ComfyUI Manager → Install Custom Nodes → search "comfy-ui-minecraft-pbr", install, restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/jasonjgardner/comfy-ui-minecraft-pbr
# then restart ComfyUI

No model downloads, no pip extras - torch does the FFTs.

Gotchas

Derived AO and height are approximations, and they're honest about it. They're plenty for the AO baked into _n and for POM parallax, but don't feed the height into a displacement map and expect true sculpting detail - FFT integration smears high-frequency noise. And if your normal isn't tileable but you skip seamless, you'll see the integration seam down one edge. One more: because the packer derives these automatically, you only need this node when you want to see and edit the channels first. For a straight Chord-to-shader run, you can skip it entirely and let the packer do it invisibly.

CategoryMinecraft PBR

Inputs (8)

NameTypeDefaultDescription
normalIMAGETangent-space normal map (OpenGL Y-up).
seamlessBOOLEANfalseTreat the input as tileable.
ao_strengthFLOAT2.00–10
ao_blurINT50–64
height_intensityFLOAT1.000–1
height_minFLOAT0.250–1Deepest POM value; 0.25 = 25% block depth for Minecraft.
height_invertBOOLEANtrueFlip POM direction so bumps rise.
height_maskoptMASKWhere 1, flatten height to height_min.

Outputs (2)

NameTypeDescription
aoMASK
heightMASK