Nodes/ComfyUI-camera-shake-node/Batch Camera Shake (Subtle)
ComfyUI Node

Batch Camera Shake (Subtle)

Make your AI footage stop looking like a tripod was bolted to the floor

By tylervw99·Created 3 months ago·Updated 3 months ago· 0
Batch Camera Shake (Subtle)
  • images
  • IMAGE
seed0
translate_px2.0
rotate_deg0.15
scale_pct0.5
freq1.0
smoothing0.85
distributioneven
min_intensity0.50
borderreflect

Your generated video is technically perfect and absolutely dead. That's the classic tell of a model that holds the camera perfectly still - AnimateDiff's default output and a good chunk of LTX and Wan generations look like they were shot on a locked-off tripod, and "static" is a constant complaint in video-model feedback threads. Batch Camera Shake (Subtle) is the cheap fix: it walks through your image batch frame by frame and nudges each one with a small, smoothed translate, rotate, and scale, so the sequence reads as handheld instead of frozen.

It's called "subtle" and it means it. Defaults are 2px of movement, 0.15° of rotation, 0.5% zoom - the kind of micro-motion your eye registers as "alive" rather than "shaky." That's the right instinct for a first pass; actual shake is what you dial in on purpose.

How it works

Under the hood it's refreshingly honest. For each of the four channels (x translate, y translate, rotation, scale) it generates uniform random noise, smooths it with an exponential moving average controlled by smoothing, and normalizes so different seeds give similar intensity. Those samples are generated at a length derived from freq and linearly interpolated to your batch's frame count, so a higher freq means the shake changes more often. Each frame then gets its own 2×3 affine matrix and the whole batch goes through PyTorch's F.grid_sample with bilinear sampling. Pure post-process, no models, no downloads - just torch and numpy, which ComfyUI already ships.

Because the noise is seeded from your seed value, identical inputs give identical motion every run. That's gold for iterating: find a look you like, and it's reproducible.

The inputs that matter

You can honestly leave most of these alone at first. The ones worth touching:

  • seed - set it to something other than 0 if you want a different motion path. Same seed, same shake, always.
  • translate_px and rotate_deg - the two knobs that actually read as "shake." If the defaults feel too subtle, push translate toward 4–6px and rotation toward 0.5° and see what breaks.
  • smoothing - higher is floatier and more natural; drop it toward 0.2 and you get nervous, handheld-phone footage. Default 0.85 is a good starting point.
  • freq - 1.0 is a fine default; bump it for quicker, more nervous movements on longer clips.

The rest are the tools of the trade, not the basics. distribution shapes intensity over time - even for uniform shake, center to peak mid-clip, ease_out to start moving and settle back to the origin like a camera coming to rest. min_intensity sets the floor of that curve and is only active when distribution isn't even. border controls the edges: reflect (default) and replicate mirror or stretch edge pixels so you don't see a gap, while zeros just shows black - pick that one knowing you'll see borders wherever the shake is large. And scale_pct is the zoom wobble, the "camera breathing closer and further" bit.

The single output is the same IMAGE batch, same frame count, same resolution, just nudged. Wire it straight into a VAE decode → video save path, or back into an img2img pass - it doesn't care.

Installing it

Two options, same result. Via ComfyUI Manager, search for "ComfyUI-camera-shake-node" and hit install. Or do it by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/tylervw99/ComfyUI-camera-shake-node.git

Restart ComfyUI and it shows up under image/transform as Batch Camera Shake (Subtle). That's the whole install - no requirements.txt, no model to fetch, because it only depends on what ComfyUI already ships.

Where people get burned

Two traps, both real. First: this node does nothing on a single image. It's built for a batch of frames - [B, H, W, C] - so feed it one frame and you just get a tiny static offset that looks like a crop error, not shake. It earns its keep between frame generation and video encoding, where B is your clip's frame count.

Second: crank the movement way up and the transform starts eating your frame edges. reflect and replicate handle that gracefully, but the black bars from zeros are easy to miss until you've already rendered the whole clip. And know that scale_pct maxes out at 10 and smoothing at 0.99 - the extremes stop looking like "handheld" and start looking like "handheld during an earthquake."

Is this a replacement for camera-motion LoRAs or real camera rigging? No - those give you intentional moves (dolly, pan, orbit), while this gives you incidental life, the thing that makes a clip feel filmed rather than rendered. They're not competitors; the shake is the layer you put on top after you've already decided the actual camera move.

Categoryimage/transform

Inputs (10)

NameTypeDefaultDescription
imagesIMAGEInput image batch to apply camera shake effect to
seedINT00–2147483647Random seed for reproducible shake patterns. Same seed = same shake motion
translate_pxFLOAT2.00–50Maximum horizontal/vertical movement in pixels. Higher = more pronounced shake
rotate_degFLOAT0.150–10Maximum rotation angle in degrees. Subtle values (0.1-0.3) look natural
scale_pctFLOAT0.50–10Maximum zoom variation as a percentage. Simulates camera moving closer/further
freqFLOAT1.00.1–5Shake frequency multiplier. Higher = faster, more frequent shake changes
smoothingFLOAT0.850–0.99Motion smoothness. Higher = smoother, floaty movement. Lower = jittery, nervous shake
distributionCOMBOevenIntensity distribution over time. even=uniform, center=peaks in middle, ease_out=settles to origin
min_intensityFLOAT0.500–1Minimum intensity as fraction of maximum (0-1). Only active when distribution is not 'even'. 0=full range, 1=no variation
borderCOMBOreflectEdge handling: reflect mirrors edges, replicate extends edge pixels, zeros fills with black

Outputs (1)

NameTypeDescription
IMAGEIMAGE