SynkitFX Metablob
Metablob Turns a Still Into Animated Halftone Goo — on CPU, No Models
- image
- mask
- video
- frames
- blob_mask
Drop in one photo and this node hands back a finished little video clip: a dot grid whose dot sizes follow the picture, fused into organic blobby shapes, animating over time. It's the "dots that melt together" look you see in title cards and motion graphics, and it does it with zero model weights and zero VRAM - plain numpy and OpenCV on the CPU. Animated intro loops, halftone music-video vibes, or just making a flat still feel alive - this is the cheapest way to get there in ComfyUI.
It's one half of the msch-synkitfx pack from mariobilly; the other half, SynkitTracker, draws HUD tracking boxes on top. Each works fine alone, and together they chain into a full "synthwave surveillance" package.
How it works
It's a mechanical effect, not a neural one. The image is divided into a grid with spacing set by cell_size (smaller = more, finer dots). Each cell reads a local signal from the image - which signal is your drive choice: dark, bright, saturation, or edges. Below threshold a cell produces no dot at all; above it, the dot grows with the signal, shaped by contrast (a gamma on the drive, so raising it keeps only the strongest areas) and dot_size.
Then the good part: the node builds a summed distance field across every dot and takes an iso-line of it, so overlapping dots add up and fuse - that's what turns a grid of discs into gooey metaball shapes. merge runs the show: 0 gives clean separated dots, 1 melts everything into big blobs. softness is edge anti-aliasing in pixels, and grid = hex switches to a honeycomb layout.
The inputs you'll actually touch
- image - a still or an IMAGE batch. A still gets expanded to
frames(default 48) atfps(24), so the defaults give you a two-second clip; a real video batch is processed as-is and those two inputs are ignored. - drive and merge - these two set the whole look.
brighton dark footage withmergearound 0.6 is the classic "luminous blobs" poster look;darkwith low merge reads as halftone dots. - animate - off, pulse (all dots swell together), breathe (each dot on its own seeded rhythm), drift (the grid slides), flicker (dots pop in and out), and combos like the default
breathe+drift.anim_speedsets cycles per second;anim_amounthow strongly it moves. - color, opacity, background - blob color as a hex string like
#C6FF00, and whether the blobs sit on the original image, black, white, ortransparent_black. - mask (optional) - wire a MASK in and dots only appear where the mask is bright; the mask multiplies the blob alpha per frame.
And there's seed for reproducing a run. threshold is worth nudging too: raise it to silence weak noise dots and keep only strong areas.
Outputs and wiring
Three sockets: video (native VIDEO), frames (the processed IMAGE batch), and blob_mask (a MASK describing where the blobs are). The canonical chain is to feed frames into the next effect (or Save Video) and pull video only off the last node in the stack - that's how the shipped example chains Metablob → Tracker → the core Save Video node. Real transparency? transparent_black is blobs on black, not alpha in an MP4 - that's what blob_mask is for.
Install
The README's path is the reliable one, since ComfyUI Manager/Registry listing is still "pending" for this pack:
cd ComfyUI/custom_nodes
git clone https://github.com/mariobilly/msch-synkitfx.git
cd msch-synkitfx
python -m pip install -r requirements.txt # same Python env as ComfyUI
Windows portable uses .\python_embeded\python.exe instead of python. Dependencies are just numpy, torch, and opencv-python - nothing heavy. Restart ComfyUI and refresh the browser.
One heads-up: the author has since folded everything into the unified msch-comfyui-nodes pack, and the README calls this repo "superseded" - kept for existing installs and links. Both work, but don't install both at once or you'll get duplicate node registrations; follow that repo's migration guide if you switch.
Gotchas
- H.264 wants even dimensions. Odd-sized frames can fail on encode - resize to even width/height if Save Video complains.
- CPU speed. It's pure CPU, and a long frame count at small
cell_sizeis a lot of per-cell math. Great for short loops; don't brute-force hundreds of frames at full res. - On older ComfyUI builds the VIDEO socket can come back empty (the node degrades gracefully) - use
framesplus your usual Save Video path instead.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| frames | INT | 481–4096 | Frames to render from a still. Ignored when the input is already a video batch. |
| fps | FLOAT | 241–120 | — |
| cell_size | INT | 143–128 | Grid spacing in pixels. Smaller = more dots. |
| drive | COMBO | dark | What makes a dot grow: dark areas, bright areas, colour saturation or edges. |
| threshold | FLOAT | 0.350–1 | Input values below this produce no dot. Raise to keep only strong areas. |
| dot_size | FLOAT | 1.000.1–4 | Dot radius multiplier relative to the cell size. |
| merge | FLOAT | 0.500–1 | 0 = clean separated dots, 1 = dots melt into big blobs. |
| contrast | FLOAT | 1.500.2–5 | Gamma on the drive signal. Higher = only the strongest areas get dots. |
| softness | FLOAT | 0.500–3 | Edge anti-aliasing in pixels. |
| color | STRING | #C6FF00 | Blob colour as hex. |
| opacity | FLOAT | 1.000–1 | — |
| background | COMBO | original | What the blobs are drawn on. 'transparent_black' = blobs on black, use the MASK output for alpha. |
| grid | COMBO | square | 2 options: square, hex |
| animate | COMBO | breathe+drift | pulse = all dots grow/shrink together. breathe = every dot on its own rhythm. drift = grid slides. flicker = random dots pop in and out. |
| anim_speed | FLOAT | 1.000–10 | Cycles per second. |
| anim_amount | FLOAT | 0.350–1 | — |
| seed | INT | 00–4294967295 | — |
| maskopt | MASK | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| frames | IMAGE | — |
| blob_mask | MASK | — |