Nodes/BrainDead Nodes/BD Pack Channels
ComfyUI Node

BD Pack Channels

Roughness in R, metal in G, AO in B — BD Pack Channels builds engine textures

By BizaNator·Created 8 months ago·Updated 3 days ago· 15
BD Pack Channels
  • red_image
  • red_mask
  • green_image
  • green_mask
  • blue_image
  • blue_mask
  • alpha_image
  • alpha_mask
  • image
  • alpha
  • debug_preview
red_default0.00
red_invertfalse
green_default0.00
green_invertfalse
blue_default0.00
blue_invertfalse
output_alphafalse
alpha_default1.00
alpha_invertfalse
width_override0
height_override0
luma_standardbt709

Game engines love packed textures. Instead of shipping four separate grayscale maps, you stash roughness in the red channel, metallic in green, AO in blue, and maybe height or a mask in alpha - one file, one sampler, less memory. That's what BD Pack Channels does: it takes up to four sources and merges them into the RGBA channels of a single output image. It's the inverse of splitting channels, and it's the node you reach for at the end of any map-derivation pipeline when the maps have to become an engine texture.

Every channel slot works the same way, so once you learn one you know all four. Each slot (red, green, blue, alpha) accepts an IMAGE, a MASK, or both:

  • IMAGE only - its luminance becomes that channel (weighted per luma_standard, BT.709 by default; BT.601 matches Photoshop's Desaturate if you're comparing with a legacy tool).
  • MASK only - the mask is the channel.
  • Both - the mask gates the image (image × mask), handy for cutting a channel to a region.
  • Neither - filled with that channel's default_value (0 for RGB, 1 for alpha so it stays opaque).

Each slot also has an invert toggle, and width_override / height_override let you force a common size - all channels get resized to match the first non-None source by default.

The one thing beginners miss: alpha

output_alpha defaults to false, so if you wire an alpha source and nothing happens, that's why. Two nice touches: wiring alpha_image or alpha_mask auto-enables 4-channel output, and an RGBA image wired into the alpha slot uses its alpha channel directly (an RGB one gets luminance). Default alpha when nothing's wired is 1.0, so an RGB-only output stays opaque if you do enable it.

You get three outputs: image (RGB or RGBA), alpha (the alpha channel as a MASK, useful for a preview), and debug_preview - a 2×2 grid showing each channel as grayscale with a colored corner tag. That debug view is genuinely the fastest way to confirm you packed the right maps into the right channels.

Where it lives

This is the terminal node of the pack's "Game-Engine Packing" workflow - isolate parts, balance luma, crop and center, then pack R/G/B. It's also the manual version of what BD Mouth Parts does automatically (lips/teeth/tongue → RGB). Pair it with BD Derive PBR Maps, which emits albedo, normal, roughness, metallic and AO separately, and pack them into ORM/ARM with this node before export.

Install

It ships in ComfyUI-BrainDead: Manager search "BrainDead", or clone + pip install -r requirements.txt. The pack uses the newer V3 API, so update ComfyUI first if the nodes don't appear.

The classic failure here isn't the node, it's the luma interpretation. If you feed it a color map and expect the raw red channel back, remember it computes luminance instead - if you specifically want R, G, or B raw, the pack's own channel resolver supports direct channel picks, but this node's visible inputs default to luminance. For exact channel math, convert to grayscale the way you want it upstream and feed masks or already-gray images. And if your packed texture looks dark in the engine, check you didn't pack grayscale floats in 0–1 into channels that the viewer expects in 8-bit - the values are right, the preview is just showing normalized range.

Category🧠BrainDead/Segmentation

Inputs (20)

NameTypeDefaultDescription
red_imageoptIMAGEIMAGE source for the RED channel — its grayscale luminance becomes R.
red_maskoptMASKMASK for the RED channel. If red_image is also wired, this MASKS it (image × mask); alone, the mask IS the channel.
red_defaultoptFLOAT0.000–1Value to fill RED with when neither red_image nor red_mask is wired.
red_invertoptBOOLEANfalseInvert the resolved RED channel before packing.
green_imageoptIMAGEIMAGE source for the GREEN channel — grayscale becomes G.
green_maskoptMASK
green_defaultoptFLOAT0.000–1
green_invertoptBOOLEANfalse
blue_imageoptIMAGEIMAGE source for the BLUE channel — grayscale becomes B.
blue_maskoptMASK
blue_defaultoptFLOAT0.000–1
blue_invertoptBOOLEANfalse
output_alphaoptBOOLEANfalseIf True, output is 4-channel RGBA instead of RGB. Use the alpha_image/alpha_mask/alpha_default inputs to set the A channel.
alpha_imageoptIMAGEIMAGE source for the ALPHA channel. If RGBA, the alpha channel is used directly. If RGB, luminance is computed. Wiring this auto-enables output_alpha.
alpha_maskoptMASKMASK source for the ALPHA channel (wins over alpha_image). Wiring this auto-enables output_alpha.
alpha_defaultoptFLOAT1.000–1Value to fill ALPHA with when no alpha source is wired (default 1.0 = opaque).
alpha_invertoptBOOLEANfalse
width_overrideoptINT00–8192Override output width. 0 = use first non-None source's width.
height_overrideoptINT00–8192Override output height. 0 = use first non-None source's height. All channels are resized to this dimension.
luma_standardoptCOMBObt709When an IMAGE input is provided (not MASK), luminance is computed using this weighting. RGB → luminance weighting: bt709 (default): 0.2126 R + 0.7152 G + 0.0722 B — modern sRGB/Rec.709 standard. Use for Unity/Unreal, AI pipelines, modern display work. bt601: 0.299 R + 0.587 G + 0.114 B — legacy NTSC weights, matches Photoshop 'Desaturate' and older tools. average: (R+G+B)/3 — simple, not perceptual.

Outputs (3)

NameTypeDescription
imageIMAGE
alphaMASK
debug_previewIMAGE2x2 grid showing each channel as greyscale. Top-left=R, top-right=G, bottom-left=B, bottom-right=A. Each quadrant has a small colored corner tag (red/green/blue/white) to identify the channel.