Nodes/ComfyUI Minecraft PBR/Minecraft PBR - Pack labPBR
ComfyUI Node

Minecraft PBR - Pack labPBR

The node that turns PBR maps into labPBR textures your shader will actually read

By jasonjgardner·Created 3 months ago·Updated 3 months ago· 0
Minecraft PBR - Pack labPBR
  • basecolor
  • normal
  • roughness
  • metalness
  • ao
  • height
  • emission
  • porosity
  • sss
  • metal_mask
  • height_mask
  • albedo
  • specular
  • normal
hardcoded_metalnone
flip_normal_ytrue
swap_normal_xyfalse
derive_ao_heighttrue
include_heighttrue
seamlessfalse
compute_porosityfalse
compute_sssfalse
compute_emissionfalse
emission_threshold0.85
emission_knee0.10
ao_strength2.0
ao_blur5
height_intensity1.00
height_inverttrue

If you've ever fed a PBR map set into a Minecraft shader and gotten a texture that looks like painted plastic, this is the missing step. Minecraft PBR - Pack labPBR takes the four maps a material estimator spits out - basecolor, normal, roughness, metalness - and repacks them into labPBR 1.3, the channel-coded format that Iris and OptiFine shaders actually read. It doesn't run any model, it doesn't call any API, and it needs no key. It's a packer: the boring, essential job of translating your AI output into something a game engine believes.

What it produces

Feed it the standard four maps and you get three RGBA textures out: albedo, specular (the _s texture), and normal (the _n texture). That's it. Wire all three into the pack's Save labPBR node and you have a working resource pack set.

The clever bit is what goes inside those alpha channels. labPBR is a channel-code standard, and this node does the encoding for you:

  • _s: R = perceptual smoothness (1 − √roughness), G = F0 / metal id (dielectric ≈ byte 10, named metals 230–237, custom 255), B = porosity (0–64) or SSS (65–255 - SSS wins per-pixel), A = emission (255 = none, 0–254 = level).
  • _n: R/G = normal X/Y in DirectX Y-down, B = ambient occlusion, A = POM height for parallax (0.25 = 25% block depth).

Everything stays linear - the pack applies no gamma anywhere, which is what shaders expect from these channels.

Inputs that matter

  • basecolor, normal, roughness, metalness - the big four. roughness and metalness accept an IMAGE or a MASK, so Chord's 1-channel outputs wire straight in.
  • derive_ao_height (default on) - computes AO and height from the normal when you don't supply them. Leave it on.
  • flip_normal_y (default on) - converts an OpenGL Y-up normal to DirectX Y-down. Turn it off only if your input is already DirectX.
  • hardcoded_metal - the F0 id for metallic pixels (none/custom/iron/gold/aluminum/chrome/copper/lead/platinum/silver). "none" uses custom (255), where the shader reads F0 from the albedo.
  • compute_porosity / compute_sss / compute_emission - auto-derive those channels, or pass your own via the optional ao, height, emission, porosity, sss, metal_mask, and height_mask inputs.
  • seamless - treat the input as tileable; turn this on for anything that will repeat, which for game textures is most things.

Install

ComfyUI Manager → Install Custom Nodes → search "comfy-ui-minecraft-pbr" (or "Minecraft PBR"), install, restart. Or by hand:

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

No model downloads, no extra Python packages - torch, numpy and Pillow already ship with ComfyUI. This is one of the rare packs you can install and forget.

Gotchas

Where people get burned: the default assumes an OpenGL Y-up normal, which is what Chord and most generators emit - flip it only if your source is already DirectX. And don't pipe the specular or normal outputs into the stock SaveImage node; it drops alpha, which corrupts the channel-coded textures. Use the pack's Save labPBR node, which writes faithful linear RGBA PNGs. Finally, remember roughness/metalness images get collapsed to luminance if they're multi-channel - if your roughness lives in one RGB channel, extract it first.

Reference for the standard itself: shaderlabs.org/wiki/LabPBR_Material_Standard.

CategoryMinecraft PBR

Inputs (26)

NameTypeDefaultDescription
basecolorIMAGE
normalIMAGETangent-space normal (OpenGL Y-up).
roughnessIMAGE,MASK
metalnessIMAGE,MASK
hardcoded_metalCOMBOnoneMetal id for metallic pixels; 'none' uses custom (255).
flip_normal_yBOOLEANtruelabPBR _n stores DirectX Y-down; flip an OpenGL Y-up normal (default). Disable only if your input is already DirectX.
swap_normal_xyBOOLEANfalse
derive_ao_heightBOOLEANtrueDerive AO + height from the normal when not supplied.
include_heightBOOLEANtrueWrite derived height into _n alpha (POM).
seamlessBOOLEANfalse
compute_porosityBOOLEANfalse
compute_sssBOOLEANfalse
compute_emissionBOOLEANfalse
emission_thresholdFLOAT0.850–1
emission_kneeFLOAT0.100–1
ao_strengthFLOAT2.00–10
ao_blurINT50–64
height_intensityFLOAT1.000–1
height_invertBOOLEANtrue
aooptIMAGE,MASKOverride derived AO.
heightoptIMAGE,MASKOverride derived height (e.g. Chord 'Normal to Height' IMAGE).
emissionoptIMAGE,MASKOverride extracted emission.
porosityoptIMAGE,MASK
sssoptIMAGE,MASK
metal_maskoptIMAGE,MASKPer-pixel metal-id map (from Pack Metal Masks); overrides hardcoded_metal/metalness on painted pixels.
height_maskoptMASKWhere 1, flatten POM height.

Outputs (3)

NameTypeDescription
albedoIMAGE
specularIMAGE
normalIMAGE