Nodes/comfyui-vs-glassmatte/VS Glass Band Mask
ComfyUI Node

VS Glass Band Mask

Finding the empty glass neck without drawing it yourself

By andrewclass1·Created 4 days ago·Updated 4 days ago· 0
VS Glass Band Mask
  • image
  • bottle_mask
  • glass_mask
  • report
◄modeauto►
◄top_frac0.043►
◄bottom_frac0.185►
◄brightness_threshold0.60►
◄search_limit_frac0.30►
◄grow_px6►

The interesting part of a glass bottle - the part that has to be transparent rather than just cut out - is the strip of empty glass between the cap and the liquid line. Everything below that is essentially opaque; everything in the band is a window you can see the background through. So the pipeline regenerates only that strip on black, and VS Glass Band Mask is the node that finds it. Get this mask wrong and you either regenerate solid bottle body (and lose detail you already had) or leave a hairline of real glass in your black plate and get a ghost seam in the final matte.

How the auto mode thinks

Feed it the white plate and the bottle silhouette and it does something pleasantly crude: it walks rows down from the top of the bottle, and for each row measures the mean luma of the central fifth of the bottle's span at that row. Rows above brightness_threshold (default 0.6) count as bright. Then:

  • It skips the cap, identified as a sustained dark run of at least 1.5% of the bottle's height - which handles the cap plus its highlight.
  • The band starts at the first bright row after that.
  • The band ends at the first sustained dark run after that - the liquid.

The 1.5%-of-height minimum is what tolerates thin dark lines inside the neck, like ring shadows on the glass, instead of ending the band early. And there's a sanity gate: if the resulting band is less than 3% of the bottle's height, it gives up on auto and falls back to manual. The report tells you which happened:

{ "mode_used": "auto", "rows": [312, 489],
  "as_fraction_of_bottle": [0.0431, 0.1852] }

The README's healthy reading is mode_used: auto. If you're seeing manual on a bottle that should have worked, the auto-detection didn't find a cap and a liquid line it believed - check search_limit_frac next.

When to go manual

mode: manual uses top_frac and bottom_frac as fractions of the bottle (not the canvas), from the top of the bottle mask downward. The defaults - 0.043 and 0.185 - are the reference bottle's band, so on a stock bottle you can leave it in manual and get the same answer without any detection risk. On a bottle with a dark or heavily-tinted neck, auto will refuse and manual is the honest option. The band is intersected with the bottle mask afterwards, so it never bleeds outside the silhouette.

grow_px (default 6) dilates the band to give the inpainting some overshoot. It only grows downward and sideways - the source explicitly re-zeroes everything above the band's top row so it can never creep up into the cap. brightness_threshold and search_limit_frac are auto-mode tuning: how bright counts as glass, and how far down the bottle to look for the cap before giving up.

Outputs are glass_mask (a MASK) and report. The mask is used twice: as the inpaint region when you run Flux Fill on black, and by VS Plate Drift Check to exclude the regenerated glass from its opaque-region comparison.

Install

Manager → VS Glass Matte, or:

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

Zero dependencies beyond torch and numpy, no checkpoints. The Flux Fill model this feeds is your own business and lives wherever your other Flux models live.

Where people get burned

Auto mode is only as good as the silhouette. A bottle mask that includes the cast shadow means the "bottle height" it measures against is taller than the bottle, and every fraction - including the 1.5% run threshold - shifts. That's the most common reason mode_used comes back manual: the mask wasn't the bottle, it was the bottle plus its shadow.

Second, this is a luma heuristic on a generated image. If the model put a bright reflection on the cap, the "cap is dark" assumption can fail and the band starts too high, eating into the cap. You'll see it in the mask preview as a band that clips the top of the neck - drop search_limit_frac, or switch to manual and use the fractions.

Third: for genuinely semi-transparent parts of the glass, remember you're asking a diffusion model to invent what's behind the bottle. The result is plausible, not measured, and there's no way around that with any model - it's the same structural limit that makes segmentation models bad at matting.

CategoryView Source/Glass Matte

Inputs (8)

NameTypeDefaultDescription
imageIMAGE—
bottle_maskMASK—
modeCOMBOauto2 options: auto, manual
top_fracFLOAT0.0430–1—
bottom_fracFLOAT0.1850–1—
brightness_thresholdFLOAT0.600–1—
search_limit_fracFLOAT0.300.05–1—
grow_pxINT60–128—

Outputs (2)

NameTypeDescription
glass_maskMASK—
reportSTRING—