Nodes/TrentNodes/Latent-Aligned Mask (with VAE)
ComfyUI Node

Latent-Aligned Mask (with VAE)

Masks that line up with the latent grid

By TrentHunter82·Created 9 months ago·Updated 4 days ago· 36
Latent-Aligned Mask (with VAE)
  • mask
  • vae
  • aligned_mask
  • latent_preview
  • compression_factor
expansion_pixels8
blur_latent_units1
threshold0.50
override_compression0

Diffusion doesn't work on pixels. It works on a compressed latent grid - typically 8× smaller than your image - and when you hand a mask to a latent inpainting sampler, that mask gets downsampled to the latent resolution. Here's the thing nobody warns you about: a clean pixel-space mask edge lands between latent cells when it's scaled down, and the result is the classic "black edge" or halo around your inpainted region. Latent-Aligned Mask (with VAE) is the fix: it processes your mask in latent space so the edges land exactly on the latent grid, then resizes back to full resolution with no artifacts.

It's the flagship of four mask variants in this pack, and the only one that needs a VAE plugged in - because it uses the VAE to measure the exact compression factor instead of assuming.

How it works

The mechanism is the interesting part. It's five steps, all on the GPU:

  1. Downsample the mask to latent resolution with area averaging (the "correct" way to shrink a mask - it respects coverage).
  2. Expand in latent space using max-pooling, so the mask grows enough to swallow the latent cells at its boundary. This is what prevents black edges.
  3. Blur the boundary with a small Gaussian - in latent units, which is the right scale.
  4. Threshold back to binary.
  5. Upsample with nearest-neighbor, so the final pixel-space mask has perfectly blocky, latent-aligned edges.

Because the mask's edge after all that always falls on a latent-cell boundary, the sampler never sees a half-occupied cell, and the "black fringe" class of artifact just stops happening.

Inputs that matter

  • mask - your source mask.
  • vae - the VAE whose latent space you're targeting. The node auto-detects the compression factor by probing the VAE (it handles Wan's 3D video VAE and standard 2D ones, falling back to 8×). override_compression lets you force a value (0 = auto).
  • expansion_pixels - how much to grow the mask, in latent units. Default 8 is a good start; bump it for loose inpaint regions.
  • blur_latent_units - softness of the boundary. 1 is subtle, fine for most work.
  • threshold - the binary cutoff, 0.5 default.

Outputs: aligned_mask (the ready-to-use mask), latent_preview (a look at what the latent actually saw), and compression_factor - an INT telling you what it detected, which is genuinely useful when you're debugging why a mask feels blockier or smoother than expected.

Install

Part of TrentNodes:

cd ComfyUI/custom_nodes
git clone https://github.com/TrentHunter82/TrentNodes.git
cd TrentNodes
pip install -r requirements.txt

Restart, look under Trent/Masks. No extra weights - this is torch tensor math against your existing VAE.

Gotchas

The auto-detect isn't magic. For standard VAEs it's reliable, but a VAE that doesn't expose its compression cleanly makes it fall back to the 8× default - which is right for Wan and most SD-family models but wrong for a 4× or 16× VAE. If your inpaint seams look weird, check the compression_factor output and pass it back in via override_compression. Also: the mask comes back binary after thresholding. If you wanted a soft, feathered mask, you'll want to blur it after - this node's output is meant for latent inpaint, not compositing.

CategoryTrent/Masks

Inputs (6)

NameTypeDefaultDescription
maskMASK
vaeVAE
expansion_pixelsINT80–64Expand mask in LATENT space (prevents black edges)
blur_latent_unitsINT10–8Blur amount in latent units (softens boundaries)
thresholdFLOAT0.500–1Binary threshold after processing
override_compressionoptINT00–16Manual compression factor (0=auto-detect, typically 8)

Outputs (3)

NameTypeDescription
aligned_maskMASK
latent_previewMASK
compression_factorINT