Nodes/ComfyUI-JH-PixelPro/Filters: Motion / Zoom Blur
ComfyUI Node

Filters: Motion / Zoom Blur

Faking a Panning Shot Inside ComfyUI

By jetthuangai·Created 6 months ago·Updated a day ago· 6
Filters: Motion / Zoom Blur
  • image
  • mask
  • image
◄modemotion►
◄angle0►
◄distance20►
◄zoom0.15►
◄center_x0.50►
◄center_y0.50►

The most upvoted advice on why AI video looks fake is unglamorous: "there's no motion blur." Same for stills that are supposed to read as captured rather than generated - a perfectly crisp background behind a moving subject is a tell. Filters: Motion / Zoom Blur (JHPixelProMotionZoomBlur) puts that effect in the graph, and more importantly it lets you apply it only to the background, which is what a panning photograph actually looks like.

Two looks, one node

mode picks the physics:

motion averages along a straight line centred on each pixel - a camera or subject moving during the exposure. angle sets direction (−180 to 180; 0 is horizontal, 90 is vertical), distance sets the streak length in pixels (0 to 1000).

zoom averages along the rays toward a centre point - turning the zoom ring mid-exposure. Pixels near center_x/center_y barely change; the frame edge streaks most. zoom (0 to 0.9) is the strength: the edge blurs over that fraction of its distance to the centre. 0.1 to 0.3 reads as natural; past 0.4 you're doing an obvious effect rather than a fake photograph.

The mask is the whole point

The optional mask blurs where it's white and leaves the rest alone. This is not a convenience feature - it's the difference between "a blurry picture" and "a panning shot". Connect an inverted subject mask and the subject stays razor sharp while the world smears past behind it.

Two details make that look convincing rather than cut out: soften the mask edge (a hard mask gives the subject a rim of unblurred background, which reads as a Photoshop job), and pick the streak direction to match the gesture you're implying - a person walking left should get angle near 0 with the streak along the direction of travel.

For the zoom variant, move the centre onto the subject's face or eye. A zoom burst pulls attention, and pointing it at empty sky wastes the effect.

Why it's cheap to run

Both modes are box blurring along a 1-D path, but not naively: a box of n1 × n2 taps is identical to a box of n1 taps at spacing 1 followed by n2 taps at spacing n1, so a blur of D pixels costs about 2·√D bilinear warps instead of D samples. Zoom does the same trick in log-radius, where scalings add. Each warp is a grid_sample with reflection at the borders, and everything is averaged, so overall brightness is preserved - you don't get the dark edges a naive smear would produce.

Practical numbers from the author: at 4K on a GPU, a 200 px motion blur is about 1.4 s, zoom about 0.1 s, under 1 GB VRAM. ComfyUI hands images over on the CPU and the node moves the work to the GPU when it can, falling back to CPU on out-of-memory.

Output is a single image at input size. motion with distance under 0.5, or zoom at 0, returns the input unchanged - so "nothing happened" usually means a parameter that didn't take.

How to install it

Manager: search ComfyUI-JH-PixelPro, install, restart ComfyUI. Manual:

cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt

Then Add Node → ComfyUI-JH-PixelPro → filters. Pack requirements: Python 3.10+, kornia>=0.7, MediaPipe ≥ 0.10, OpenCV ≥ 4.8, SciPy ≥ 1.10. No model files, no downloads - this node is pure tensor maths, and CPU works if that's all you have.

Where it goes wrong

Distance doesn't scale with resolution. This is the number-one thing to internalise: distance is in pixels, not a fraction of the frame. 60 px at 2K is a subtle streak; 60 px at 4K is almost invisible. Scale it with your output size - the author's own guide suggests 200 px at 4K for a strong pan.

A visible rim around the subject. Hard mask edge. Soften it (Mask Edge Smoother, or any feather), and remember the mask should be inverted relative to your subject mask - white gets blurred.

Everything blurred including the subject. You connected the subject mask instead of its inverse. Mask Combine will invert it.

It looks like a smear, not motion. Too long a streak on a busy background. Go back 30% and add it in steps.

A wobbly, boxy quality at high distance. It's a box filter, not a true shutter - long streaks on fine repeating texture can band. If that shows, blur a copy at half strength through a soft mask instead of going longer.

Since this pack has no Reddit trail at all - no threads, no shared workflows from users, nothing - you can't lean on someone else's settings. Which is fine here: this is one of the few nodes where you can reason from the numbers. Pixels of streak, direction of travel, edge fraction of the zoom. Change one, look, change the next.

CategoryComfyUI-JH-PixelPro/filters

Inputs (8)

NameTypeDefaultDescription
imageIMAGEImage to blur.
modeCOMBOmotionmotion = movement in one direction. zoom = streaks toward a centre point, like zooming during the exposure.
angleFLOAT0-180–180motion: direction in degrees (0 = horizontal, 90 = vertical).
distanceFLOAT200–1000motion: blur length in pixels.
zoomFLOAT0.150–0.9zoom: strength; the frame edge streaks over this fraction of its distance to the centre.
center_xFLOAT0.500–1zoom: centre across the image (0 = left, 1 = right).
center_yFLOAT0.500–1zoom: centre down the image (0 = top, 1 = bottom).
maskoptMASKBlur only where the mask is white (e.g. the background).

Outputs (1)

NameTypeDescription
imageIMAGE—