Four-Way Quick Align
Nudge B, C and D onto A's frame before the glitch mixer chews on them
- images_a
- images_b
- images_c
- images_d
- aligned_a
- aligned_b
- aligned_c
- aligned_d
The Four-Way Undulating Glitch Mixer has one quiet requirement: it wants four clips that are roughly the same framing and size, because it blends them per-pixel under a travelling wave. Real footage rarely cooperates. Your second camera angle is a hair wider, the third is cropped differently, and clip D has the subject sitting slightly off-centre. Four-Way Quick Align is the fix-up node you run before the mixer - it rescues sloppy multi-cam takes without any model, keyframe, or hand-rotoscoping.
What it does
Input A is treated as the reference canvas and passed through completely unchanged. Inputs B, C and D each get their own independent transform: X/Y offset in pixels, scale, and rotation in degrees. The node resizes B–D to A's dimensions first, then applies the transform, and hands you back all four aligned batches so they can feed straight into the mixer.
That "A is the reference, A has no controls" part trips people up the first time. There are no a_scale or a_offset_x widgets, and that's deliberate - you move the world to fit A, not A to fit the world. If it's A that's wrong, swap which clip you label as A.
The inputs that matter
For each of B, C, D you get the same four:
*_offset_x/*_offset_y- shift in pixels. This is where most of the fixing happens.*_scale- 0.25× to 4×. Nudge head size to match A.*_rotation- degrees, mostly for small eye-line corrections.
Plus two global settings:
interpolation-bicubic,bilinear, ornearest. Start bicubic.fill_mode- what fills the edges the transform exposes:white,black,border(stretch the edge pixels), orreflection(mirror them).
The author's workflow advice is worth following in order: adjust scale first, then X/Y position, then - and only then - rotation, and only for small corrections. Rotating footage by more than a couple of degrees reads as a tilt, not an alignment. For isolated heads on a white background, start with fill_mode: white and bicubic and the seams disappear.
A nice under-the-hood detail
When a transform is a no-op (zero offset, scale 1, zero rotation), the node returns the original tensor instead of running a grid_sample pass over it. That's not just an optimisation for its own sake - at 1280×1280 a redundant full-batch copy is real memory you don't want to burn, especially when you're streaming long clips through VHS.
Outputs and wiring
aligned_a, aligned_b, aligned_c, aligned_d - four IMAGE batches, in order, into the mixer's images_a…images_d. That's the whole loop:
VHS Load Video ×4 → Four-Way Quick Align → Four-Way Undulating Glitch Mixer → VHS Video Combine
Install
cd ComfyUI/custom_nodes
git clone https://github.com/jsterlingvids/ComfyUI-UndulatingGlitch.git
Restart ComfyUI and search for "Undulating Glitch" (image/video/undulating glitch category). No model downloads, no extra Python packages - just the PyTorch ComfyUI already bundles. Manager can install it by URL, but the pack isn't on the Registry yet, so git clone is the dependable route.
Gotchas
The node aligns composition, not everything else - the mixer still needs matching frame rates and durations across all four clips (its frame_alignment setting can trim, loop, or stretch shorter ones if you don't want to fix that by hand). And while fill_mode: reflection or border looks fine for small shifts, once you're moving a head several hundred pixels you'll see the fill; that's a sign to re-crop the source instead of hiding the gap.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| images_a | IMAGE | — | |
| images_b | IMAGE | — | |
| images_c | IMAGE | — | |
| images_d | IMAGE | — | |
| b_offset_x | FLOAT | 0-4096–4096 | — |
| b_offset_y | FLOAT | 0-4096–4096 | — |
| b_scale | FLOAT | 1.000.25–4 | — |
| b_rotation | FLOAT | 0.0-180–180 | — |
| c_offset_x | FLOAT | 0-4096–4096 | — |
| c_offset_y | FLOAT | 0-4096–4096 | — |
| c_scale | FLOAT | 1.000.25–4 | — |
| c_rotation | FLOAT | 0.0-180–180 | — |
| d_offset_x | FLOAT | 0-4096–4096 | — |
| d_offset_y | FLOAT | 0-4096–4096 | — |
| d_scale | FLOAT | 1.000.25–4 | — |
| d_rotation | FLOAT | 0.0-180–180 | — |
| interpolation | COMBO | 3 options: bicubic, bilinear, nearest | |
| fill_mode | COMBO | 4 options: white, black, border, reflection |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| aligned_a | IMAGE | — |
| aligned_b | IMAGE | — |
| aligned_c | IMAGE | — |
| aligned_d | IMAGE | — |