Gen2 Tile Masks
The per-tile masks that make tiled inpaint actually work
- tile_layout
- masks_list
In the tiled-inpaint workflow, the splitter cuts the image into tiles with overlap halos, but the halo is context - it should stay as it is, not be regenerated. The model needs to know that: "regenerate my base region, leave the halo alone." That's what per-tile masks are for, and this node builds them from the splitter's layout. For every tile it emits a mask that's 1.0 over the tile's owned base region and 0.0 over the halo, so when you composite the regenerated tiles back, only the bases get written and the halos' original content is preserved.
How it works
It takes the tile_layout from Gen2 Tile Splitter and walks each split, building a mask that frames the expanded tile exactly (base plus halo) with a solid 1.0 rectangle over the base region. The masks come out in the same order as the splitter's tiles_image_list, so masks_list[i] belongs to tile i. That ordering guarantee is the whole point - you can zip them through a sampler and a merger without any bookkeeping.
The input that matters: mask_blend_pixels
The only real control is mask_blend_pixels (default 0, 0–512). At 0 you get a hard-edged mask - a sharp 1.0/0.0 step at the base boundary. Turn it up and the mask gets a symmetric Gaussian feather across that boundary, with a total transition band of roughly mask_blend_pixels pixels (sigma = blend_px / 2).
Why feather? Two reasons. One, a hard mask edge pasted into an image can leave a visible contour where the regenerated content meets the untouched context. Two, the seam-merge algorithms in the merger (linear/gaussian falloff) work with these feathered masks to smooth the transition. For a first pass you'll often start at 0 and only feather when seams show up.
Output
masks_list - a list of MASK tensors, one per tile, same order as the splitter. That's the entire output. Wire it into the merger's optional masks_list input; when the merger runs with blend_mode = "none" and masks wired in, it uses your masks directly for the paste instead of its built-in base-only logic - so your feathered masks are honored even on the fast path.
Installation
Part of petmycat/ComfyUI-gen2. Install via ComfyUI Manager (search "ComfyUI-gen2"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/petmycat/ComfyUI-gen2
cd ComfyUI-gen2
pip install -r requirements.txt
Like the rest of the tiling section, this node needs scipy (it uses scipy.ndimage.gaussian_filter for the feathering). Missing scipy → the tiling nodes don't register and the rest of the pack still works; pip install scipy fixes it.
Common issues
- Masks look identical at
mask_blend_pixels = 0and the seams are visible. That's expected at 0 - you've turned feathering off. Bumpmask_blend_pixelsup (32 is a reasonable start) and re-run. - "tile_layout is not a valid GEN2_TILE_LAYOUT" error. You wired something that isn't a splitter layout into
tile_layout. It must come from the Gen2 Tile Splitter. - Masks misaligned with tiles. They're only as correct as the layout. As long as
tile_layoutis the same object the splitter produced, order and geometry line up by construction - so don't pass a layout from a different image/settings into a mask node for another one.
It's a small node with a narrow job, but it's the difference between "tiled inpaint that repaints your whole image" and "tiled inpaint that fixes only what you pointed at."
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| tile_layout | GEN2_TILE_LAYOUT | — | |
| mask_blend_pixels | INT | 00–512 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| masks_list | MASK | — |