Light Wrap Composite (Timeline)
Making a composite stop looking pasted-on
- foreground
- background
- mask
- image
- summary
The finishing pass nobody talks about
You've cut your subject out, dropped them on a new background, and it looks... cut out. Sharp edges, no interaction with the light around them. That's the tell of every AI composite, and it's the exact problem light wrap solves.
A light wrap takes the background, blurs it, and adds a little of that blur back on top of the subject's edges - so the background's color and brightness bleed onto the subject like it's actually standing in that light. It's the compositing move that makes a pasted subject read as in the scene instead of on it. In Nuke and After Effects you've got a node for this; in ComfyUI you usually hack one together from blur + mask nodes. MKRLightWrapComposite is the hack, packaged.
It comes from the MKRShift_Nodes pack, which is a giant grab-bag of creative and finishing tools by Cris K B. Pure Python, no model files, no API keys - it runs on numpy, torch, and Pillow, all of which ComfyUI already ships.
How it works
The mechanism is exactly what you'd build by hand, in one node:
- Blur the background with a Gaussian of radius
wrap_radius(default 16). - Find the subject's edge - from your optional
maskif you give one, or from aFIND_EDGESfilter on the foreground if you don't. - Multiply the blurred background by that edge, scale by
strength, and add it on top of the foreground.
It operates on full image batches, so it works frame-by-frame on a video, and it'll warn (not crash) if foreground and background batch lengths mismatch - it just uses the shorter one.
The inputs that matter
Three inputs do almost all the work:
foreground(IMAGE) andbackground(IMAGE) - the subject and the scene. Background is resized to match the foreground.wrap_radius- how far the bleed extends. Higher for soft, dreamy halos; lower for a tight, subtle wrap.strength(default 0.35) - how much of the wrap to actually add. This is the one you'll nudge constantly; 0.35 is a sane starting point, and 2.0 is full-laser-show.
The mask (MASK) input is optional but I'd call it the difference between good and great. Without it, the node falls back to edge detection on the foreground, which grabs every texture detail and hair strand - you can get noise glows on busy subjects. Feed it your actual alpha or segmentation mask and the edge comes out clean. The outputs are image (the composite, same batch size) and a summary JSON string with frame count and settings - useful if you're feeding a text/log node.
Install
MKRShift_Nodes has no pip requirements and no models to download, so install is trivial:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Then restart ComfyUI. Or just open ComfyUI Manager, search "MKRShift Nodes", and install from there. This node doesn't need ffmpeg - that only matters for the pack's video encoding nodes.
Where people get burned
Batch size. If your foreground is a single image and your background is a 32-frame video batch, you get 32 wraps of the same frame - which is fine, but it's a habit to notice early. And if you skip the mask, remember the edge detection is luma-based; a dark subject on a bright background will wrap differently than the reverse. The fix is the same in both cases: give it a real mask and tune strength, not wrap_radius. Light wrap is one of those $0 deterministic operations that saves you from re-rolling a generation because "the composite just doesn't sit right" - reach for it before you touch the sampler again.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| foreground | IMAGE | — | |
| background | IMAGE | — | |
| wrap_radius | INT | 161–256 | — |
| strength | FLOAT | 0.350–2 | — |
| maskopt | MASK | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| summary | STRING | — |