AP Flow Composite
The node that decides who wins — blending warped and original frames without ghosting
- original_images
- warped_images
- valid_mask
- occlusion_mask
- effect_mask
- composited_images
- composite_alpha
You've warped a frame with flow and computed an occlusion mask. Now you have two versions of every pixel - the original and the warped - and the composite node is the referee that decides, per pixel, which one shows. It's the last step of the pack's core temporal chain (APGetRAFTOpticalFlow → APFlowOcclusionMask → APApplyRAFTOpticalFlowMasked → here), and it's where a flow workflow either looks like clean video or falls apart into ghosting.
The idea is simple: warped pixels are what you want where the warp is trustworthy; original pixels are what you keep where it isn't. The art is deciding "trustworthy" - and this node gives you three levers to decide it.
The mechanism
APFlowComposite takes original_images, warped_images, valid_mask (from the apply node), and occlusion_mask (from the occlusion node), and builds an alpha per pixel. The base alpha is valid_mask × (1 − occlusion_mask) - trust the warp where the flow was consistent and not occluded. Then three dials refine that alpha:
alpha_mode-flow_confidence(default),flow_confidence_x_mask, ormask_only. The first uses pure flow validity; the second multiplies by an optionaleffect_mask;mask_onlymakes the effect mask the whole story. For the README's recommended anti-blur setup you wantflow_confidence_x_mask, with the apply node'swarped_maskwired intoeffect_mask.use_difference_gate- the smartest feature here. When enabled, the node computes the per-pixel difference between warped and original, and only lets the alpha through where the difference exceedsdifference_threshold(default 0.01). The point: if the warp didn't actually change a pixel, the composite shouldn't touch it either. This is what keeps background that shouldn't have moved from being repainted. The README recommends a low threshold like 0.005–0.02 for the anti-ghost setup.mask_threshold- binarizes theeffect_maskabove a value, for when you want a hard mask rather than a soft one.blend_strength,feather,invert_occlusion- blend amount (1.0 = full alpha, under 1.0 = partial), alpha edge feathering, and a polarity flip for the occlusion mask if yours is inverted relative to expectations.
Outputs
composited_images is your finished blend. composite_alpha is the alpha that produced it - a MASK you can preview or reuse, which is handy for debugging "why is my background getting touched" (answer: the alpha is too high there; check your difference gate).
The wiring that actually gets results
The README's "professional anti-blur compositing" is worth quoting because it's the difference between a soft blurry result and a crisp one:
- Connect
warped_maskfromAPApplyRAFTOpticalFlowMaskedto this node'seffect_mask. - Set
alpha_mode = flow_confidence_x_mask. - Enable
use_difference_gate = truewith a lowdifference_threshold(0.005–0.02).
That combination confines the composite to genuinely-warped regions and leaves untouched background alone. Skip it and you'll get the classic symptom: background areas subtly blurring every frame because the composite is blending warped-but-identical pixels with the original at some alpha.
Installing it
Standard pack install: ComfyUI Manager (search "AP_OpticalFlow"), or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/adampolczynski/ComfyUI_AP_OpticalFlow
python -m pip install -r custom_nodes/ComfyUI_AP_OpticalFlow/requirements.txt
Restart. Dependency is torchvision>=0.15 only.
The one thing to check first
If your composite output looks like the warped frame is leaking in where it shouldn't, your occlusion mask polarity is probably flipped - try invert_occlusion. If it looks like nothing is being composited, your effect_mask is too tight or use_difference_gate is swallowing everything at a too-high difference_threshold. Both are quick dial-turns, not node-bugs.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| original_images | IMAGE | — | |
| warped_images | IMAGE | — | |
| valid_mask | MASK | — | |
| occlusion_mask | MASK | — | |
| alpha_mode | COMBO | flow_confidence | 3 options: flow_confidence, flow_confidence_x_mask, mask_only |
| mask_threshold | FLOAT | 0.0000–1 | — |
| use_difference_gate | BOOLEAN | false | — |
| difference_threshold | FLOAT | 0.0100–1 | — |
| difference_feather | INT | 00–64 | — |
| blend_strength | FLOAT | 1.000–2 | — |
| feather | INT | 00–64 | — |
| invert_occlusion | BOOLEAN | false | — |
| effect_maskopt | MASK | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| composited_images | IMAGE | — |
| composite_alpha | MASK | — |