PBR Pack
Four loose maps into one engine-ready texture
- ao_image
- roughness_image
- metalness_image
- alpha_image
- ao_mask
- roughness_mask
- metalness_mask
- alpha_mask
- image
- packing_info
If you've ever exported material maps from ComfyUI and then stared at your game engine going "okay, where does each one go," x1PBRPack is the node that ends that session. It takes your separate AO, roughness, metalness, and alpha maps and packs them into a single engine-ready texture in the layout your renderer actually wants - ORM, ORMA, RMA, or MRA - with named channel slots instead of guesswork.
It's the natural endpoint of the pack's Surface/Maps family. The whole story the family tells - derive scalar maps with x1RoughnessMap, x1MetalnessMap, x1CavityMap, then combine - ends here. The author's docs even spell out the reference flow: x1CavityMap / x1RoughnessMap / x1MetalnessMap → x1PBRPack.
How it works
You connect maps in semantic slots - ao_image, roughness_image, metalness_image, alpha_image - and the node handles the physical channel packing for you. The four layouts:
- ORM - R=AO, G=Roughness, B=Metalness (the classic single RGB texture; no alpha)
- ORMA - same plus alpha in the A channel
- RMA - R=Roughness, G=Metalness, B=AO (Unreal-adjacent convention)
- MRA - M/R/A order
One genuinely useful feature: roughness_source. Set it to glossiness when your "roughness" input is actually a gloss map (the inverse), and the node inverts it into roughness automatically. Gloss vs roughness confusion is one of the most common material-pipeline bugs, and this removes it as a failure mode.
Any slot you leave unconnected gets its fill_* default - fill_ao 1.0, fill_roughness 1.0, fill_metalness 0.0, fill_alpha 1.0. Those defaults are the physically sane ones (dielectric, fully rough, no AO darkening), so a two-map pack still produces a valid texture.
Each slot also accepts a matching *_mask input, so you can drive any channel from a mask instead of an image.
Outputs
Just two, which is refreshing:
image- the packed RGB or RGBA texture, ready to save or hand offpacking_info- a string summary of the chosen layout and which sources populated each channel
packing_info earns its keep: when you come back to a workflow and can't remember whether R is AO or roughness, it tells you.
Honest positioning
This is a semantic packer - it understands PBR. For arbitrary channel layouts (packing your own custom maps), the pack's x1ChannelPack is the more general tool, and the author says so. Reach for x1PBRPack when you're doing standard material work, x1ChannelPack when you're doing something weird. And if you're new to PBR maps entirely: the community thread where people keep asking "how do I get roughness/metalness/AO nodes" is exactly the gap this family fills - derive the maps, pack them here, done.
Installing it
ComfyUI Manager (search "MKRShift Nodes") or:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Restart, no requirements, no model downloads, no ffmpeg. The pack is a big install for one node, but if you're doing material work you'll use half the Surface branch alongside it.
Where people trip
Mixed map ranges. If your roughness map came from an un-normalized source, packing it as-is bakes the bad range into your texture - normalize with x1ScalarMapAdjust or the map node's own normalize_mode before packing. And double-check roughness_source: feed a gloss map in with roughness selected and your material will look inverted (mirror-smooth where it should be rough), and the error is subtle enough to survive a whole review.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| layout | COMBO | 4 options: orm, orma, rma, mra | |
| roughness_source | COMBO | 2 options: roughness, glossiness | |
| fill_ao | FLOAT | 1.0000–1 | — |
| fill_roughness | FLOAT | 1.0000–1 | — |
| fill_metalness | FLOAT | 0.0000–1 | — |
| fill_alpha | FLOAT | 1.0000–1 | — |
| ao_imageopt | IMAGE | — | |
| roughness_imageopt | IMAGE | — | |
| metalness_imageopt | IMAGE | — | |
| alpha_imageopt | IMAGE | — | |
| ao_maskopt | MASK | — | |
| roughness_maskopt | MASK | — | |
| metalness_maskopt | MASK | — | |
| alpha_maskopt | MASK | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| packing_info | STRING | — |