Compose + Match (per-frame)
Composite a regenerated element so the seam disappears
- destination
- source
- mask
- previous_frames
- image
You regenerated a frame with a video model to add an element - lava on the floor, a prop, a person - and now you want to keep only the masked region and composite it over your original footage. Straight composite, right? Wrong. The VAE round-trip shifts the whole regenerated frame's grading, and a straight paste shows a seam at the mask border. ComposeColorMatch is a proper compositing node: it puts source over destination through a mask, then corrects the insert so it matches the plate, per frame, on a video.
This is the VFX-insert workhorse of the pack, and it understands why video inserts fail in a way most composite nodes don't.
How it works
Core wiring: destination (the original footage), source (the regenerated frame with the new element), mask (the region to keep from the source). Compositing is always source-over-destination: out = dest*(1-mask) + src*mask.
Then the correction modes, which is where the real thinking lives:
correction- defaultGrade match (surround). Because outside the mask the source and destination are the same scene (you regenerated the whole frame), the difference between them there is pure grading drift. The node fits a per-channel transform (original ≈ a·generated + b) on those surround pixels and applies it to the source inside the mask. The element keeps its own colors - lava stays lava - only its luminance/contrast is shifted to line up with the plate. This needs an aligned full-frame regeneration; it does not need a color matcher.Color match (palette)is the older distribution-based approach (the Kijaicolor-matcherlineage): match one image's color distribution to another. Fine for matching two different plates, actively wrong for the VFX-insert case - it would tint the lava green to match the scene.Offdisables correction, giving you a plain composite.
The secondary trims handle a specific VAE artifact: regenerated content comes back slightly desaturated and with lifted ("milky") blacks. saturation (luma-preserving scale), black_point (pull blacks back down), and edge_falloff (feather those trims inward from the mask edge, so the border stays perfectly matched). grade_fit chooses between Gain + offset (default) and Offset only for the fit.
Then the palette path has its own controls - method (mkl, hm, reinhard, mvgd, and hybrid combos), colormatch_reference, reference_region, multithread. And for video there's the standout: temporal_anchor, which re-matches each iteration's element to the previous iteration's corrected tail (via the optional previous_frames input), so VAE drift can't compound frame over frame. anchor_strength and anchor_frames tune that.
Where it fits
Any "regenerate the frame, keep only the insert" pipeline - and that's a huge chunk of modern local VFX and character-insert work. It's the finishing stage: generate with the model, mask the element, composite here with grade matching on, and the insert reads as part of the original shot instead of a sticker on it.
Installing it
Part of Mickmumpitz-Nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/mickmumpitz/ComfyUI-Mickmumpitz-Nodes.git
or ComfyUI Manager → search "Mickmumpitz" → install → restart. No model downloads; opencv-python (already a pack dep) does the heavy lifting.
Troubleshooting
- Seam still visible - check
grade_fitand that the source is genuinely the same shot as the destination outside the mask. Grade match only works when the surround content aligns. - Insert looks tinted - you're probably on
Color match (palette). Switch back toGrade match (surround)for inserts; palette matching tints content toward the scene. - Milky, washed-out insert - raise
black_pointa touch and/or boostsaturation; that's the VAE round-trip signature this node exists to fix. - Flicker across iterations - enable
temporal_anchorand wire inprevious_frames. Drift compounding is exactly what it's for.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| destination | IMAGE | — | |
| source | IMAGE | — | |
| mask | MASK | — | |
| correction | COMBO | Grade match (surround) | 3 options: Grade match (surround), Color match (palette), Off |
| strength | FLOAT | 1.000–2 | — |
| saturation | FLOAT | 1.000–3 | — |
| black_point | FLOAT | 0.0000–0.2 | — |
| edge_falloff | INT | 00–512 | — |
| grade_fit | COMBO | Gain + offset | 2 options: Gain + offset, Offset only |
| surround_band | INT | 00–1024 | — |
| colormatch_reference | COMBO | Destination | 2 options: Source, Destination |
| method | COMBO | mkl | 6 options: mkl, hm, reinhard, mvgd, hm-mvgd-hm, hm-mkl-hm |
| reference_region | COMBO | Outside mask | 3 options: Outside mask, Full frame, Inside mask |
| multithread | BOOLEAN | true | — |
| temporal_anchor | BOOLEAN | false | — |
| anchor_strength | FLOAT | 1.000–2 | — |
| anchor_frames | INT | 00–99 | — |
| previous_framesopt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |