WarpWiggle Transition
Warp-blend two clips together with bands, blocks or a slit-scan seam
- images_a
- images_b
- images
Every edit needs the occasional cut that feels like something happened - not just a wipe, but a clip that visibly warps and wobbles into the next one. WarpWiggleTransition (display "WarpWiggle Transition") is that move as a ComfyUI node: it takes two video clips, overlaps their tails and heads through a spatial warp field with a moving blend seam, and hands back the joined sequence. It's part of the MSCH Nodes pack's Warp Wiggle trio, and it's the glue node for music-video-style cutting where every transition is a little event.
How it works
You feed images_a and images_b (both IMAGE batches, frames in order). The last transition_frames of A meet the first transition_frames of B; B is resized to A's dimensions, and during the overlap a blend seam sweeps across while the frames are displaced through a warp field. What comes out is one continuous batch: len(A) + len(B) minus the effective overlap - which is why you should hang onto that frame count if you're timing subsequent nodes.
The warp_pattern is the visual personality: horizontal_bands and vertical_bands displace in stripes, blocks shatters into square cells (sized by block_size), radial ripples from the center, and slit_scan drags the transition through time-sliced strips. warp_strength and warp_frequency shape the displacement field itself; wiggle_amplitude/wiggle_frequency/wiggle_axis add the trembling motion on top - that's the "wiggle" in the name. noise_amount, parallax, and chromatic_aberration (per-channel RGB separation along the seam, default 0.3) are the polish that makes it feel like a designed effect rather than a morph.
The inputs that matter
transition_frames- overlap length. Bigger = a slower, longer reveal; too big relative to your clips eats the whole edit.sweep_direction- which way the seam moves (top-to-bottom, center-out, random_blocks…), withsweep_softnessblurring the seam so it doesn't read as a hard line.easing-ease_in_out(default) for smooth pacing;snapif you want the warp to hit abruptly at the end.edge_mode- what the warp does at frame borders (zeros/border/reflection); set it if you see dark seams at clip edges.
seed makes the whole thing reproducible.
Wiring it
The node is a pure IMAGE-in / IMAGE-out joiner, so it slots between two rendered clips and the encoder: …clip A → WarpWiggleTransition ← clip B… → Save Video. The pack's docs call out that the output count is the two lengths minus the overlap - use that if you need exact frame math downstream (e.g., feeding a beat-synced timing node). It's frame-accurate and model-free, so iteration is cheap; render both clips once, then hunt for the transition you like.
Install
One of 35 nodes in the unified MSCH Nodes pack - no models, no separate repo:
cd ComfyUI/custom_nodes
git clone https://github.com/mariobilly/msch-comfyui-nodes.git
cd msch-comfyui-nodes
python -m pip install -r requirements.txt
(ComfyUI Manager: search "MSCH Nodes" / msch-comfyui-nodes, restart.) It runs on plain torch/Pillow work, so it loads even if the pack's heavier optional components aren't installed.
Gotchas
The big one is clip length: transition_frames must be smaller than the shorter clip's frame count, or the overlap math collapses and you get a blank or repeated section. Second, mismatched resolutions - B gets resized to A, so feed them already compatible or you'll see a quality step mid-transition. And if you're aiming for a beat-accurate transition, remember this node has no notion of audio: do your beat math upstream, then set transition_frames to the exact frame span the beat gives you. Defaults are a fine starting point, but warp_pattern, sweep_direction, and easing are where the effect actually gets its character - cheap to try, so try them.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| images_a | IMAGE | — | |
| images_b | IMAGE | — | |
| transition_frames | INT | 162–600 | — |
| warp_pattern | COMBO | horizontal_bands | 5 options: horizontal_bands, vertical_bands, blocks, radial, slit_scan |
| warp_strength | FLOAT | 0.180–1 | — |
| warp_frequency | FLOAT | 5.00.5–60 | — |
| wiggle_amplitude | FLOAT | 0.050–0.5 | — |
| wiggle_frequency | FLOAT | 7.00.5–60 | — |
| wiggle_axis | COMBO | both | 3 options: horizontal, vertical, both |
| block_size | INT | 484–512 | — |
| noise_amount | FLOAT | 0.350–1 | — |
| sweep_direction | COMBO | top_to_bottom | 6 options: top_to_bottom, bottom_to_top, left_to_right, right_to_left, center_out, random_blocks |
| sweep_softness | FLOAT | 0.220.01–1 | — |
| easing | COMBO | ease_in_out | 5 options: ease_in_out, linear, ease_in, ease_out, snap |
| edge_mode | COMBO | zeros | 3 options: zeros, border, reflection |
| chromatic_aberration | FLOAT | 0.300–1 | — |
| parallax | FLOAT | 0.50-1–1 | — |
| seed | INT | 00–4294967295 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |