Generate Seam Mask
The mask that fixes the seams your tiled upscale leaves behind
- IMAGE
Tiled upscaling solves one problem and quietly creates another. When you want a 4K image out of a 1024px source on a 6GB card, you can't denoise the whole thing at once - you split it into overlapping tiles, run KSampler on each, and stitch them back together. The stitching is where it falls apart: every tile boundary can leave a visible "cut line" where the blend doesn't quite land. GenerateSeamMask exists to draw a mask of exactly those boundaries, so you can run a second, targeted denoise pass on the seams and only the seams. It's the patch that makes the patchwork invisible.
What it actually is
It's the single custom node shipped in ethanfel/ComfyUI_UltimateSGUpscale, a small pack that replicates the core of UltimateSDUpscale (the old tiled-upscaling workhorse, usually bundled in Impact Pack) as a transparent workflow built from ComfyUI's own built-in nodes. The whole pack is one node plus one example workflow - no model downloads, no API key, no requirements.txt. If you've seen the classic tiled upscale where the seams show, this is the seam-fix half of that recipe, rebuilt so you can inspect every step instead of trusting a black box.
How it works
The node reproduces SplitImageToTileList's tiling math: stride is tile_size - overlap, tiles walk across the image with that stride, and each adjacent pair of tiles shares an overlap region. The mask puts a band centered on the midpoint of each overlap - which is where the seam actually lives. In binary mode those bands are hard white and everything else is black. In gradient mode each band is a linear ramp that peaks at the seam center and fades to zero over seam_width pixels, which is what makes it usable with a DifferentialDiffusion node so seam centers get full denoising while the edges melt into the surrounding image.
The inputs that matter
Only a few, and only one real gotcha:
- image_width / image_height - just wire these straight from a GetImageSize node.
- tile_width / tile_height / overlap - these must match the tiling in your main pass. This is the one thing that burns people.
- seam_width (default 64) - how wide the fix band is. Too narrow and the seam pokes through; too wide and you're denoising parts that were fine.
- mode -
binaryfor a hard mask fed through ImageToMask into SetLatentNoiseMask,gradientfor the DifferentialDiffusion route.
The output is a single IMAGE: a mask with white bands at seam positions, black elsewhere.
Installing it
The pack is one node, so install is boring in the good way:
cd ComfyUI/custom_nodes
git clone https://github.com/ethanfel/ComfyUI_UltimateSGUpscale.git
Restart ComfyUI and it shows up as Generate Seam Mask under image/upscaling. ComfyUI Manager can also find it by searching "UltimateSGUpscale". There are no model files to fetch. The one real dependency is a recent enough ComfyUI: it needs the built-in SplitImageToTileList and ImageMergeTileList nodes, added upstream in PR #12599. If you search your node list and those aren't there, update ComfyUI - don't blame the pack.
Troubleshooting
- The bands don't line up with the actual seams. You changed a tile size or overlap in pass one and didn't mirror it here. The node has no way to know what pass one did; it trusts you. Keep GetImageSize wired in and the two passes in lockstep.
- The mask is completely black. Your image fits in a single tile, so there are no seams - nothing to fix, and the second pass is wasted compute. Skip it.
- Hard edges even in gradient mode. The gradient only earns its name if a DifferentialDiffusion node is consuming it; fed to SetLatentNoiseMask on its own it still denoises a hard band.
The seam problem this fixes is as old as tiled upscaling - the classic A1111-era advice was "more overlap, more mask blur" to hide cut lines. This is the more surgical version: find the exact seam, fix only that. It's a niche helper, but if you're doing print-size upscales on a modest card, it's the difference between a clean result and one you keep zooming in on, frowning.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image_width | INT | 204864–16384 | Width of the image (from GetImageSize). |
| image_height | INT | 204864–16384 | Height of the image (from GetImageSize). |
| tile_width | INT | 102464–8192 | Tile width used in the main tiled redraw pass. |
| tile_height | INT | 102464–8192 | Tile height used in the main tiled redraw pass. |
| overlap | INT | 1280–4096 | Overlap used in the main tiled redraw pass. |
| seam_width | INT | 648–512 | Width of the seam bands to fix (in pixels). |
| mode | COMBO | binary | binary: hard 0/1 mask. gradient: linear falloff for use with Differential Diffusion. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |