BD Atlas Pack
Tile a pile of images into one game-ready atlas, layout JSON included
- images
- image_1
- image_2
- image_3
- image_4
- image_5
- image_6
- image_7
- image_8
- masks
- atlas
- mask
- layout
If you've ever hand-packed a sprite sheet in Photoshop and re-derived the UV rectangles by eye, you'll appreciate BD Atlas Pack. It takes a batch of images and tiles them into a single grid atlas - and hands you a JSON layout with the exact per-cell pixel and normalized-UV rects so a game engine (or a shader) can pull each cell back out without you doing math.
This is the node behind the pack's Atlas / Flipbook workflow. It's the kind of plumbing that only feels boring until you need it: viseme sheets for lip-sync (7 visemes into one 2048×1024 sheet), sprite flipbooks, or packing a character's part textures into a single map. The engine-facing detail that makes it worth using rather than hand-rolling is the layout output - game engines need those normalized UV rects, and getting them from a hand-packed sheet is a chore.
How the sources stack up
The node concatenates inputs in a fixed order: the batched images IMAGE first (each frame becomes one cell, in batch order), then the individual image_1 through image_8 slots, then masks - where mask[i] supplies the alpha for cell i. If a mask batch isn't wired, an RGBA image's own alpha is used; otherwise cells are opaque.
The inputs that matter
- columns / rows - both default to 0, meaning auto. Columns auto to roughly square (
ceil(sqrt(count))); rows auto toceil(count / columns)and expand if there aren't enough. Leave them at 0 and you get a sensible grid; set columns explicitly when you want a specific aspect ratio. - cell_width / cell_height - 0 means "use the widest/tallest input." Set them to force a uniform cell.
- fit_mode -
containfits the whole image inside the cell and pads (no crop),covercenter-crops the overflow,stretchignores aspect. Contain is the safe default for sprites; cover is what you want for a uniform texture atlas where every cell must fill. - padding and background_hex - padding pixels between cells and around the outer border; the mask atlas pad regions are always 0, so you never get bleed at the edges.
- order -
row_majororcolumn_majorfill order. - output_alpha - off by default (RGB atlas); flip it on and the atlas becomes RGBA with the mask atlas as its alpha channel.
Three outputs: the atlas IMAGE, a single-channel mask MASK, and the layout STRING (JSON with per-cell pixel rects + normalized UV rects). Wire the layout into anything that consumes text, or save it as a sidecar.
Install
Standard pack install - ComfyUI Manager → search "BrainDead", or:
cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead
pip install -r requirements.txt
Restart and it's under 🧠BrainDead/Segmentation. Like everything in this pack it needs a ComfyUI recent enough for the V3 node API. This one is pure tensor work - no models, no Blender - so it's a zero-drama node to slot into a bigger pipeline.
A practical note if you're packing game textures: pair it with the pack's BD_MaskFlatten (Voronoi alpha bleed for UV edge seams) and BD_CropAndCenter (common pivot per part) upstream, and what you pack will actually line up in-engine instead of bleeding or drifting. Atlas is only the last mile - the parts need to be prepared before they hit the grid.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| imagesopt | IMAGE | Batched IMAGE (B,H,W,C) — each frame becomes one cell, in batch order. | |
| image_1opt | IMAGE | Individual image for a cell (appended after the batch). | |
| image_2opt | IMAGE | — | |
| image_3opt | IMAGE | — | |
| image_4opt | IMAGE | — | |
| image_5opt | IMAGE | — | |
| image_6opt | IMAGE | — | |
| image_7opt | IMAGE | — | |
| image_8opt | IMAGE | — | |
| masksopt | MASK | Batched MASK — mask[i] is the alpha for cell i (aligned to the concatenated image order). If absent, an RGBA image's own alpha is used, else opaque. | |
| columnsopt | INT | 00–64 | Number of columns. 0 = auto (≈ square: ceil(sqrt(count))). |
| rowsopt | INT | 00–64 | Number of rows. 0 = auto (ceil(count / columns)). Expanded if too small to fit all cells. |
| cell_widthopt | INT | 00–8192 | Pixel width of each cell. 0 = use the widest input image. |
| cell_heightopt | INT | 00–8192 | Pixel height of each cell. 0 = use the tallest input image. |
| fit_modeopt | COMBO | contain | contain — fit whole image in cell, pad with background (no crop). cover — fill cell, center-crop overflow. stretch — resize to cell, ignore aspect. |
| paddingopt | INT | 00–512 | Pixels of background between cells AND around the outer border. |
| background_hexopt | STRING | #000000 | Background / padding fill colour (hex). Mask atlas pad regions are always 0. |
| orderopt | COMBO | row_major | row_major — fill left-to-right then down. column_major — fill top-to-bottom then right. |
| output_alphaopt | BOOLEAN | false | If True, the atlas IMAGE is RGBA (alpha = the mask atlas). Default is RGB. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| atlas | IMAGE | — |
| mask | MASK | — |
| layout | STRING | — |