Nodes/Undulating Glitch/Four-Way Quick Align
ComfyUI Node

Four-Way Quick Align

Nudge B, C and D onto A's frame before the glitch mixer chews on them

By jsterlingvids·Created 2 months ago·Updated 2 months ago· 0
Four-Way Quick Align
  • images_a
  • images_b
  • images_c
  • images_d
  • aligned_a
  • aligned_b
  • aligned_c
  • aligned_d
b_offset_x0
b_offset_y0
b_scale1.00
b_rotation0.0
c_offset_x0
c_offset_y0
c_scale1.00
c_rotation0.0
d_offset_x0
d_offset_y0
d_scale1.00
d_rotation0.0
interpolation
fill_mode

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, or nearest. Start bicubic.
  • fill_mode - what fills the edges the transform exposes: white, black, border (stretch the edge pixels), or reflection (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_aimages_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.

Categoryimage/video/undulating glitch

Inputs (18)

NameTypeDefaultDescription
images_aIMAGE
images_bIMAGE
images_cIMAGE
images_dIMAGE
b_offset_xFLOAT0-4096–4096
b_offset_yFLOAT0-4096–4096
b_scaleFLOAT1.000.25–4
b_rotationFLOAT0.0-180–180
c_offset_xFLOAT0-4096–4096
c_offset_yFLOAT0-4096–4096
c_scaleFLOAT1.000.25–4
c_rotationFLOAT0.0-180–180
d_offset_xFLOAT0-4096–4096
d_offset_yFLOAT0-4096–4096
d_scaleFLOAT1.000.25–4
d_rotationFLOAT0.0-180–180
interpolationCOMBO3 options: bicubic, bilinear, nearest
fill_modeCOMBO4 options: white, black, border, reflection

Outputs (4)

NameTypeDescription
aligned_aIMAGE
aligned_bIMAGE
aligned_cIMAGE
aligned_dIMAGE