Nodes/ComfyUI-SuperPBR/πŸ†’ SuperPBR Tile Split
ComfyUI Node

πŸ†’ SuperPBR Tile Split

How to decompose a 4K texture without feeding it 4K

By HullabaloΒ·Created 6 days agoΒ·Updated 2 days agoΒ· 0
πŸ†’ SuperPBR Tile Split
  • image
  • mask
  • image
  • mask
  • anchor_image
  • tilesig
β—„tile_size512β–Ί
β—„overlap128β–Ί

SuperMat eats 512-pixel squares. You have a 2K or 4K texture you want material maps from. The obvious move - just feed the big image in and let the node resize it - throws away every bit of detail you paid for, because SuperPBR Material resizes to resolution before the UNet sees anything. πŸ†’ SuperPBR Tile Split is the other move: cut the image into overlapping 512 squares, decompose the whole batch at native detail, stitch it back.

This is the standard tiling pattern the upscaling ecosystem runs on, applied to material extraction. Same logic as any tile-based upscaler: you're trading VRAM and passes for resolution, and the overlap exists so the seams can be blended away afterwards.

What it does to your image

Give it an image and it computes a grid. tile_size defaults to 512 - SuperMat's training resolution - and overlap defaults to 128 px. The stride is simply tile_size - overlap, so with the defaults each tile advances 384 px and the last tile in each row/column is allowed to hang past the edge. That overhang is filled with replicate padding, edges smeared outward, not black bars, which keeps the model from hallucinating a hard edge into the material.

The numbers grow fast. A 2048Γ—2048 image at 512/128 gives five tiles per axis - 25 tiles, each a full 512-square pass through the UNet. That's the real cost of tiling, and it's why the decomposition node has a batch_chunk field: 25 tiles land in one batch, and the chunk size caps how many go through the UNet and VAE at once.

tile_size up to 768 also gives good results per the README, though 512 is what the model was trained for. On overlap: bigger means more redundant compute and a wider blend zone, smaller means faster and a thinner one. Zero is legal and gives you hard seams - don't.

There's a mask input too, and it's split on the exact same grid so it stays pixel-aligned with image tiles. It's worth knowing that the code handles LoadImage's 64Γ—64 placeholder mask - the one you get when the source file has no alpha channel - by resizing it up to the image before splitting, so you don't get a mystery 64-pixel mask.

The four outputs

image is your tile batch, in row-major order with tiles as the outer dimension and batch as the inner one. That ordering is what Tile Stitch expects, so don't go rearranging tiles in between.

mask is the mask cut on the same grid - and it's genuinely empty if you didn't connect a mask, so don't wire it somewhere that assumes otherwise.

anchor_image is the interesting one: the full image, mask-composited to 0.5 gray where the mask says background, padded to the tile canvas. tilesig is a grid signature - a small bundle of geometry describing the grid. Those two go into SuperPBR Material's anchor_image and tilesig inputs, and together they switch on the global-anchor blend: one extra pass over the whole downscaled image whose low frequencies anchor every tile, which is what kills tile-to-tile colour and tone drift. This is the fix for the one thing that genuinely looks broken in naive tiling. Use both or neither - the blend only engages when both are connected.

Install

ComfyUI Manager β†’ search the pack title, or:

cd ComfyUI/custom_nodes
git clone https://github.com/Hullabalo/ComfyUI-SuperPBR.git

Restart. No dependencies, no model files for this node alone - it's grid math and padding. You need SuperMat loaded only once you actually decompose the tiles.

Two things that bite

overlap greater than or equal to tile_size raises overlap must be smaller than tile_size. Fine, but it means you can't have a "50% overlap" on a 128 tile and a 256 overlap at the same time - the field doesn't scale itself, so adjust both together when you change tile size.

And remember the tiles are square while your canvas may not be. A 3:2 image gets padded out to the grid, not squashed, so the right and bottom edge tiles are partly smeared padding. That's expected - Tile Stitch crops back to the original dimensions, so the padding is scaffolding, not output.

CategorySuperPBR

Inputs (4)

NameTypeDefaultDescription
imageIMAGEβ€”
tile_sizeINT512128–2048Tile size sent to SuperMat; 512 is what it was trained for.
overlapINT1280–1024Overlap between neighbouring tiles in px; must be < tile_size. Blend it away in TileStitch.
maskoptMASKMask; split on the exact same grid.

Outputs (4)

NameTypeDescription
imageIMAGETile batch (row-major).
maskMASKMask split on the same grid (None if not connected).
anchor_imageIMAGEFull mask-composited image padded to the tile canvas; wire into the decomposition node's anchor_image for the global-anchor blend.
tilesigTILESIGGrid signature; wire into TileStitch so it uses the same geometry.