ComfyUI Node

VS Mask Stitch

Pasting the regenerated glass back without a seam

By andrewclass1·Created 4 days ago·Updated 4 days ago· 0
VS Mask Stitch
  • base
  • patch
  • crop
  • mask
  • force_black_outside
  • IMAGE
◄feather_px2.0►

VS Mask Stitch is the other half of the pack's crop-and-stitch pair, and its job is the least glamorous and most consequential thing in the whole black-plate stage: take the model's output for the glass neck, resize it back into the exact box you cut, feather it, and lay it onto the base - then optionally force everything outside the bottle to exact black so the matte has a clean floor to subtract.

What it does, step by step

It takes base (the full-frame plate you cropped from), patch (whatever the model returned for the crop), crop (the VS_CROP receipt from VS Mask Crop) and mask. Then:

  1. Resizes the patch to the crop box's height and width - so it doesn't matter what resolution the model worked at.
  2. Blurs the full-frame mask by feather_px and slices the same box out of it.
  3. Inside the box, does a straightforward lerp: base·(1 − m) + patch·m.
  4. If force_black_outside is connected, multiplies the whole image by bottle_mask > 0.004, which snaps outside-the-bottle pixels to exact black.

Step 4 is the one to not skip, and the author's tooltip says exactly what it's for: "Bottle mask. Pixels outside it are set to exact black after stitching." The threshold is deliberately tiny (0.004) rather than 0.5, so the very edge of the silhouette stays dark instead of getting a grey halo. A halo there is a disaster later, because the difference matte reads grey next to black as partial transparency, and you end up with a soft ring of fake glass around the bottle.

Output is a single IMAGE: the black plate, complete, ready for the drift check and then the matte.

Feathered, not feathered to death

feather_px at 2 is the default and it is small for a reason. You're pasting generated glass into a region that only ever gets regenerated - there's nothing to hide behind a soft blend, because the neighbouring pixels in the band are also new. A big feather just softens your own result. If you're seeing a visibile rectangular edge at the crop boundary, the problem is upstream: the crop's padding was too small, or the model's output doesn't match the surrounding tone well enough. Bigger feather is the wrong fix, and it'll cost you a mushy transition across the whole neck.

Where feathering does earn its keep is when the mask edge is a hard segmentation boundary. 2–4 pixels of feather there is worth having.

Install

Manager → VS Glass Matte, or:

cd ComfyUI/custom_nodes
git clone https://github.com/andrewclass1/comfyui-vs-glassmatte
# restart ComfyUI

No dependencies, no models. Both halves of the crop/stitch pair are in the same pack, which is the only way the VS_CROP type works.

Where people get burned

The receipt goes stale. crop carries absolute coordinates plus the original frame size. Iterate on target_long_side or on the base image's size and re-run only the downstream path, and ComfyUI's cache might hand Stitch a box from a previous run. Symptom: the patch lands offset by a few dozen pixels, or comes back the wrong size. Re-queue the whole graph when in doubt.

Patch/base size mismatch. The patch gets resized to the box regardless, so a model that returned a different aspect ratio will be squashed into place without complaint. If your glass suddenly looks horizontally stretched, this is the reason - check what resolution your Fill node was actually feeding you.

Skipping force_black_outside. Without it, the areas outside the bottle are whatever the base plate had there minus the white contribution - usually near-black but not zero. Then the matte gives you 0.01–0.02 alpha across the whole backdrop and your PNG has a grey veil in it. Wire the bottle mask in. It's one connection and it's the difference between a clean alpha channel and a dirty one.

CategoryView Source/Glass Matte

Inputs (6)

NameTypeDefaultDescription
baseIMAGE—
patchIMAGE—
cropVS_CROP—
maskMASK—
feather_pxFLOAT2.00–64—
force_black_outsideoptMASKBottle mask. Pixels outside it are set to exact black after stitching.

Outputs (1)

NameTypeDescription
IMAGEIMAGE—