VS Align To Reference
Putting the model's bottle back where yours was
- image
- image_mask
- reference_mask
- image
- mask
- report
Send a product render to an image model and it comes back prettier and slightly wrong: the bottle is 4% taller, shifted 30 pixels left, and the label sits a hair lower than the die line. On a hero image that's fatal, because every node after this one - the label wrap, the glass band, the plate comparison - assumes the bottle is exactly where the reference silhouette says it is. VS Align To Reference does that re-registration, and hands you a JSON report telling you whether the model kept your proportions.
What it does
You give it the generated image, the generated image's own bottle mask, and the reference mask from your original render. It computes a uniform scale from bottle height (moving-mask height ÷ reference-mask height in canvas terms) and a translation from the horizontal centres of the two silhouettes, then resamples with a bilinear grid sample onto a canvas sized from the reference's aspect ratio at output_height. No rotation, no perspective, one scale factor - which is the right call for a bottle photographed flat-on, and the wrong tool for anything tilted.
The output_height default of 4096 is deliberate: the pack's whole point is 16-bit hero images, and resampling at 4K keeps the resample from being the soft step in your chain. It's step-16 and clamps at 8192.
The inputs that matter
image, image_mask and reference_mask are all required. There's no way to run this without a silhouette, so you need a mask source upstream - BiRefNet (now in ComfyUI core) or one of the RMBG packs. Worth reading up on the matting-versus-segmentation distinction if your bottle is heavily transparent, because the silhouette this node trusts is only as good as the mask you feed it.
output_height (default 4096, 512–8192) sets the canvas you get back. fill is white or black and only matters at the resample edges, where the rotated/scaled grid pulls samples from outside the original image - those come back as zero and get filled with 1.0 or 0.0.
Outputs are image, mask and report. The mask is the generated bottle's silhouette re-projected into the new frame, which is what you feed to the white-plate normaliser and the black-plate builder. The report is a JSON string:
{
"scale_src_px_per_out_px": 1.0231,
"out_size": [2304, 4096],
"bottle_width_vs_reference": 1.0042,
"status": "OK"
}
How to read the report
status is the whole reason this node is better than a hand-waved "move it a bit". It flips to a warning when the bottle's width lands more than 1.5% off the reference - which means the model changed your bottle's proportions rather than just moving it, and your label art is now going to wrap onto a cone. Healthy output is OK; anything else and I'd re-roll the generation rather than try to compensate downstream. Wire the report into whatever text-display node you use and keep it on screen while you iterate; the pack's README lists this as one of the three health checks in the pipeline.
The trap: image_mask has to be registered to the generated image, not copied from the reference. The mask is resampled to the image size if it's off, so a mismatched pair won't crash - it'll just quietly align the wrong thing. And the extent measurement ignores stray pixels below a two-pixel threshold, so a single speck of mask noise won't wreck the scale, but a big blob of mis-segmented background will.
Install
Manager → VS Glass Matte, or:
cd ComfyUI/custom_nodes
git clone https://github.com/andrewclass1/comfyui-vs-glassmatte
# restart ComfyUI
No pip installs, no weights. The one dependency that trips people up is conceptual: you must already have a segmentation model wired up, because this node and the rest of the pack all speak MASK.
Where it goes wrong
If the model returns a bottle with a different cap height than your reference, the alignment is still "correct" by the numbers - the whole silhouette scales by height - but the label band moves, and your wrap calibration is now wrong for that image. That's not a bug, it's the honest limit of fitting one uniform scale to a silhouette. The report's width ratio is your early warning.
Second: this is the node where batch processing dies. The pack works on the first image of a batch throughout, because the pipeline is built around a single hero. Run one at a time.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| image_mask | MASK | — | |
| reference_mask | MASK | — | |
| output_height | INT | 4096512–8192 | — |
| fill | COMBO | white | 2 options: white, black |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| report | STRING | — |