Multi-Layer Compose
Scale it, spin it, nudge it, done
- background_image
- layer1_image
- layer1_mask
- layer2_image
- layer2_mask
- composite
- layer1_mask
- layer2_mask
Compositing in core ComfyUI is a build-it-yourself affair: you wire a mask multiply, an alpha blend, maybe a couple of pad nodes, and pray the shapes line up. Multi-Layer Compose (category McKlinton/compositing) collapses that whole tangle into one node - take a background, paste up to two masked layers on top of it, and position each with scale, offset, rotation, and brightness knobs.
It's the finishing move of the McKlinton Pack. The Mask Node hands you a clean body-part cut-out; this node is what places that cut-out back onto a scene and makes it sit right. If you're not using the pack's VAM pipeline you can still reach for it - it's a generic two-layer compositor, just a bit rigid about it.
How it works
You give it a background_image, then for each of the two layers a layerN_image plus a layerN_mask. The layer is resized to scale × its original size with bilinear interpolation, rotated by rotation degrees (0–360), shifted by offset_x/offset_y, and blended into the background using the mask as the alpha. The math is plain pixel-space compositing - no latent tricks, no VAE round trips - so it's fast and deterministic.
The brightness control is worth a moment: below 1.0 it multiplies the layer down (darker); above 1.0 it blends the layer toward white. It's a soft-light-ish lift, not a raw multiplier, so brightening won't blow out the layer into ugly clipped highlights. Nice touch.
The three outputs:
- composite - the finished image, background with both layers pasted in.
- layer1_mask / layer2_mask - the masks after scaling, rotation, and offset. This is the useful one: it tells you exactly where each layer ended up, so you can chain the result into a further refine pass or save it alongside the composite.
The inputs that matter
For each layer the same set: layerN_scale (0–5, default 1), layerN_offset_x/y (−1000 to 1000), layerN_rotation (0–360), layerN_brightness (0–2). The sliders are grouped in the UI (Layer 1 Settings, Layer 2 Settings), which keeps the graph readable. Defaults are sane - scale 1, no offset, no rotation - so the first run is usually "paste it centered," and you tune from there.
Install
It's the same pack as the Mask Node, so if that's installed you already have this. Otherwise:
cd ComfyUI/custom_nodes
git clone https://github.com/McKlinton2/comfyui-mcklinton-pack
# restart ComfyUI
Or ComfyUI Manager, searching the pack title. No models, no extra downloads. Everything runs on torch ops that already ship with ComfyUI.
Where people get burned
- Both layers are required. There's no "layer 2 off" switch - every field in
info_schemais mandatory. Want a single-layer composite? You must still wire a second image and mask. The standard dodge is passing the background aslayer2_imagewith a zero mask, which pastes nothing and costs you nothing but a little wiring. - Scale 0 is the off switch. It returns the layer untouched rather than erroring, which is arguably the intended way to "disable" a layer. Setting scale to 0.01 instead, thinking it's a tiny version, gives you a sliver of a pixel - use 0 to skip, 0.1+ to actually shrink.
- Rotation is zeros-padded. Rotated corners fill with zero rather than extending the canvas, so spinning a layer 45° crops its corners. The mask rotates along with the layer, so you don't get black boxes composited in - but you do lose the corners of your cut-out. Rotate sparingly or plan the margin.
For heavyweight multi-layer compositing with masks, feathering, and blend modes, bigger packs do more. But for "place two things on a background and nudge them into place," this is the pack's own glue, and it does the job without a 20-node graph.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| background_image | IMAGE | — | |
| layer1_image | IMAGE | — | |
| layer1_mask | MASK | — | |
| layer1_brightness | FLOAT | 1.000–2 | — |
| layer1_scale | FLOAT | 1.000–5 | — |
| layer1_offset_x | INT | 0-1000–1000 | — |
| layer1_offset_y | INT | 0-1000–1000 | — |
| layer1_rotation | INT | 00–360 | — |
| layer2_image | IMAGE | — | |
| layer2_mask | MASK | — | |
| layer2_brightness | FLOAT | 1.000–2 | — |
| layer2_scale | FLOAT | 1.000–5 | — |
| layer2_offset_x | INT | 0-1000–1000 | — |
| layer2_offset_y | INT | 0-1000–1000 | — |
| layer2_rotation | INT | 00–360 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| composite | IMAGE | — |
| layer1_mask | MASK | — |
| layer2_mask | MASK | — |