Nodes/MKRShift_Nodes/Channel Pack
ComfyUI Node

Channel Pack

Cram four grayscales into one RGB(A) texture

By criskb·Created 7 months ago·Updated 5 months ago· 0
Channel Pack
  • red_image
  • green_image
  • blue_image
  • alpha_image
  • red_mask
  • green_mask
  • blue_mask
  • alpha_mask
  • image
  • packing_info
output_mode
fill_missing0.000

Textures are expensive, so real engines pack multiple grayscale maps into one RGB(A) image and let the shader unpack them - that's how ORM (occlusion/roughness/metalness) and RMA (roughness/metalness/AO) textures work. x1ChannelPack is the node that builds those packed textures in your graph: it takes up to four grayscale sources and packs them into a single RGB or RGBA output. From MKRShift Nodes' Surface/Tech Art branch, it's the direct counterpart to x1ChannelBreakout - the docs even say so: break out what you need, pack what you want.

The pack is young (no impressions, no community footprint I found), but this node is as simple and well-scoped as the branch gets.

How it works

Each optional input - red_image, green_image, blue_image, alpha_image - is a grayscale source for that channel of the output; the node takes luma from each image. But there's a wrinkle that makes it more flexible: the matching mask inputs override the image inputs on the same channel. Wire a red_mask into red_image's slot and the mask wins, which means you can pack directly from MASK outputs (like the mask outputs from any of the pack's scalar-map nodes) without converting masks to images first. Unused channels fall back to fill_missing (0.0 default), and when output_mode is rgba, the alpha channel defaults to 1.0 if you didn't supply one.

Outputs are just two: image (the packed texture) and packing_info (a string telling you exactly which source each channel resolved to - the debug output that saves you from "why is my green channel black" sessions).

The workflow it slots into

The classic path: derive AO, roughness, and metalness maps from your base texture (the pack's x1AOFromHeight, x1RoughnessMap, x1MetalnessMap family), then pack all three into one ORM texture with this node. The author also lists mask atlases and shader-input consolidation. And if you need to pull channels out first, that's the breakout node's job.

Inputs that matter

  • output_mode - rgb or rgba; decide this before wiring alpha
  • fill_missing - the fallback for empty channels; 0.0 gives black, but if you're packing into a mask slot that should read "none," a low value is your friend
  • The four *_image / *_mask pairs - remember masks override images

Installing

ComfyUI Manager → search MKRShift Nodes, or:

cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes

Restart ComfyUI. No models, no new dependencies.

Where people get burned

  • Masks overriding images. If you connected both an image and a mask on the same channel, the mask wins, silently. Check packing_info if a channel looks wrong.
  • Not checking packing_info. It literally reports the resolved source per channel - read it before you export, because a texture packed with the wrong channel assignment is silent until it hits the renderer.
  • Inconsistent sizes across the four inputs - the node infers a reference shape and resamples to match, but feeding wildly different resolutions is how you get unexpected results.

If you're shipping a PBR set to a game engine or a renderer, this is the node that turns your derived grayscales into the one file the shader actually wants.

CategoryMKRShift Nodes/Surface/Tech Art

Inputs (10)

NameTypeDefaultDescription
output_modeCOMBO2 options: rgb, rgba
fill_missingFLOAT0.0000–1
red_imageoptIMAGE
green_imageoptIMAGE
blue_imageoptIMAGE
alpha_imageoptIMAGE
red_maskoptMASK
green_maskoptMASK
blue_maskoptMASK
alpha_maskoptMASK

Outputs (2)

NameTypeDescription
imageIMAGE
packing_infoSTRING