VS Image Compare Deluxe
Turn 'which one is better?' into a wipe clip
- source_image
- generated_image
- frames_out
- frame_count
- fps
You've got two versions of an image and you want to actually show the difference - not make the viewer squint at a side-by-side. That's the whole job of VS Image Compare Deluxe: it chews up a source image and a generated image and spits out a batch of frames that transition between them, wipe-style. Feed that batch into a video save node and you have a before/after clip you can drop in Discord or a changelog. It's the animated cousin of rgthree's Image Comparer - that one's for sliding back and forth in the UI while you debug; this one's for producing an actual shareable clip. Different tools, same argument.
The name undersells the "Deluxe" part, honestly. There are 21 effects in the dropdown, from boring-but-useful (Fade, Dissolve) through proper retro wipes (Circle, Diamond, Star, Clock, Door Open/Close, Heart, Spiral, Venetian Blinds, Checkerboard) to goofy block effects (Falling Blocks, Random Blocks, Pixelate Reveal) and two outright gags - Push Left/Right and "Toaster Color Shift," which tints the incoming frame blue-purple like a dying CRT. The README calls the whole pack "retro nonsense" and that's about the right altitude for a few of these, but the Fade/Dissolve/wipe core is genuinely useful for upscale comparisons and prompt A/B tests.
How it works
Mechanically it's simple and that's a feature. The node takes the first frame of each input image tensor, resizes the generated one to match your source's resolution (bilinear, automatic - mismatched sizes just work), then renders frames intermediate images by blending source * (1 - mask) + generated * mask. The mask is the magic: each effect builds a normalized "score map" over the image - radius for Circle Wipe, angle for Clock Wipe, a heart-shaped implicit curve for Heart Wipe - then feathered with a smoothstep so you don't get hard seams. It's all pure PyTorch, no extra packages, and the whole thing runs on CPU fine; it's just math over one image.
Three things the code does that you'll notice: seeded random maps drive Dissolve and the block effects, so a fixed seed gives you the same transition every time. invert_pattern flips which side reveals first - a Circle Wipe becomes an iris-close, basically. And block_size only affects the block-based effects plus Venetian/Checkerboard; the geometry wipes ignore it, so don't go chasing it for a Fade.
Inputs and outputs that matter
You set maybe six of these. source_image and generated_image are the two images (order matters: source is what you started with). effect_type is the dropdown; frames (2–600, default 48) and fps (1–120, default 12) size the clip. loop_count and loop_style ("restart" or "ping_pong") make it loop; hold_frames holds the end state so the reveal doesn't snap back. easing defaults to smoothstep, which is the right call - linear wipes feel mechanical. If you want the retro video look, video_flavor has scanlines, vhs_wobble, crt_soft, and full_cheese (noise + chroma channel split - that one's the whole joke in one setting).
Outputs: frames_out is your IMAGE batch - wire it into a video combine/save node (VHS Video Combine, or a WEBP/GIF saver) because this node does not save video itself. It also returns frame_count and fps as INTs, which some save nodes want.
Install
One node, one pack, zero dependencies:
cd ComfyUI/custom_nodes
git clone https://github.com/Jackson4242/ComfyUI-VS.git
Restart ComfyUI. Or use ComfyUI Manager and search "ComfyUI-VS." There's no requirements.txt and no model download - the only imports are torch and torch.nn.functional, which ComfyUI already has. This is about as clean an install as custom nodes get.
Where people get burned
The biggest trap is assuming it saves video - it doesn't, and beginners always try it with nothing downstream. Second: only the first frame of each input is used, so don't feed it video batches expecting per-frame comparisons. Third, feather is a global default that matters most for the block wipes; if you see seams on the last frame of Random Blocks, bump it slightly. That's about it - for a pack this small, the "fiddly" column is blessedly short.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| source_image | IMAGE | — | |
| generated_image | IMAGE | — | |
| effect_type | COMBO | Fade | 21 options: Fade, Dissolve, Circle Wipe, Diamond Wipe, Star Wipe, Clock Wipe, +15 |
| frames | INT | 482–600 | — |
| fps | INT | 121–120 | — |
| loop_count | INT | 11–20 | — |
| loop_style | COMBO | restart | 2 options: restart, ping_pong |
| hold_frames | INT | 00–120 | — |
| easing | COMBO | smoothstep | 5 options: linear, ease_in, ease_out, ease_in_out, smoothstep |
| feather | FLOAT | 0.0250.001–0.25 | — |
| block_size | INT | 488–256 | — |
| seed | INT | 00–2147483647 | — |
| invert_pattern | BOOLEAN | false | — |
| toaster_tint_strength | FLOAT | 0.350–1 | — |
| video_flavor | COMBO | none | 5 options: none, scanlines, vhs_wobble, crt_soft, full_cheese |
| video_flavor_strength | FLOAT | 0.250–1 | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| frames_out | IMAGE | — |
| frame_count | INT | — |
| fps | INT | — |