LTX-2.3 Mask Blend ⚡
The seamless composite that makes video inpainting worth it
- images
- source_frames
- mask
- mask_b
- IMAGE
Video inpainting has a problem image inpainting never did: the model regenerates the whole frame, so everything outside your mask comes back close but not identical, and on video that reads as shimmer and drift. Mask Blend is the fix - a Laplacian-pyramid composite that stitches your regenerated content over the pristine originals so every pixel outside the mask is bit-identical to the source. It's the post-decode half of the LTX-2.3 removal recipe, ported faithfully from Wan2GP's _apply_ltx2_mask_blend.
The mechanism is a 7-level Laplacian pyramid blend with a soft low-res mask skirt and source sanitization inside the mask. What that buys you, in practice: no visible seam where regenerated meets original, and everything you didn't ask to touch is untouched. In a world where edit models drift on every unmasked pixel, this is the thing masked inpainting still uniquely owns.
The inputs
images- the generated (inpainted) frames, decoded. Wire from LTX-2.3 AV Decode's video output via coreGetVideoComponents.source_frames- LTX-2.3 Remove Person'ssource_framesoutput: the pristine originals you're compositing onto.mask- LTX-2.3 Remove Person'sblend_maskoutput.mask_low_res_dilation(default 6) - the soft-skirt width around the mask; the trained default is 6, and it's the main thing you'd tune if you see a seam.mask_b- optional second mask, unioned withmaskafter fitting both to a common frame count. This is the replacement-composite path:mask= the original subject's silhouette,mask_b= the generated subject's - the union is the region taken from the generated frames, so the original subject can never peek out and no extra inpainting is needed. Core'sMaskCompositecan't reconcile the differing frame counts (the 8k+1 grid round-up); this node can.
Output is a single IMAGE - the composited frames, ready for CreateVideo (with the held original audio muxed in).
Where it sits
It's stage-3 glue in the full person-replacement pipeline: remove → pose-swap → blend. Stage 1 removes the person and this node composites the clean plate back over the originals; stage 3 masks the new person's silhouette and uses mask_b to blend her onto the clean plate so the background stays the original video's own pixels.
Installing
cd ComfyUI/custom_nodes
git clone https://github.com/ChrisColeTech/ComfyUI-GGUF-Loader
pip install --upgrade gguf
Restart, and it's under 🤖 CCTech/LTX-2.3. No model files of its own.
Gotchas
It expects decoded frames on the images input - feed it latents and you'll get a confusing error or garbage, not a hint. And the mask input is RemovePerson's blend_mask, not your raw detection mask; the node needs the softened, fitted version that matches the source frames' layout. Get the pairing right and the composite is invisible; get it wrong and you'll be debugging a misaligned ghost.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | Generated (inpainted) frames, decoded. | |
| source_frames | IMAGE | LTXV23RemovePerson's source_frames output (the pristine originals). | |
| mask | MASK | LTXV23RemovePerson's blend_mask output. | |
| mask_low_res_dilationopt | INT | 60–64 | Soft-skirt width around the mask (trained default 6). |
| mask_bopt | MASK | Optional second mask, unioned with mask after both are fitted to the common frame count. For replacement composites: mask = the ORIGINAL subject's silhouette, mask_b = the GENERATED subject's - the union is the region taken from the generated frames, so the original subject can never peek out and no inpainting is needed. Differing frame counts between the two masks (the 8k+1 grid round-up) are reconciled here, which core MaskComposite cannot do. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |