ComfyUI Node

OPAC Scheduler

Organic camera-motion keyframes without hand-typing a schedule

By get-salt-AI·Created 2 years ago·Updated 2 years ago· 84
OPAC Scheduler
  • opac_perlin_settings
  • zoom
  • angle
  • translation_x
  • translation_y
  • translation_z
  • rotation_3d_x
  • rotation_3d_y
  • rotation_3d_z
use_wiggletrue
frame_count48
zoom_range0.95,1.05
zoom_tremor_scale0.05
angle_range-5,5
angle_tremor_scale0.05
trx_range-10,10
trx_tremor_scale0.05
try_range-10,10
try_tremor_scale0.05
trz_range-10,10
trz_tremor_scale0.05
rotx_range-5,5
rotx_tremor_scale0.05
roty_range-5,5
roty_tremor_scale0.05
rotz_range-5,5
rotz_tremor_scale0.05

If you've ever used Deforum, you know the drill: you hand-type a schedule string like 0:(1.02), 30:(1.05) for zoom and hope your camera move doesn't look mechanically robotic. OPAC skips the manual schedule-string writing entirely - you set a range for each classic camera parameter, and it generates a natural, wandering frame-by-frame path within that range for you.

What it does

frame_count (1–500, default 48) sets how many frames of schedule you're generating. For each of eight motion parameters - zoom, angle, and X/Y/Z translation and 3D rotation - you get a _range string (like "0.95,1.05" for zoom or "-5,5" for angle, plain "min,max" text) plus a _tremor_scale (0.01–1, default 0.05) that controls how much per-frame jitter gets applied within that range. use_wiggle (default true) turns on Perlin-noise-driven organic variation rather than a flat linear ramp between endpoints - this is the difference between a camera move that looks hand-operated and one that looks like a robot arm executing a fixed trajectory. An optional opac_perlin_settings (DICT) input lets you dial in the underlying noise generation further if the defaults don't give you the character of motion you want.

Eight LIST outputs come back, one per parameter: zoom, angle, translation_x, translation_y, translation_z, rotation_3d_x, rotation_3d_y, rotation_3d_z - matching Deforum's classic parameter names directly, so if you've built animation workflows around that vocabulary before, this maps onto it cleanly.

Where it fits

This is a schedule generator, not an executor - it produces the per-frame values, and something else in your graph has to actually consume them frame by frame (this pack's own OPACList2ExecList bridges a schedule into ComfyUI's native per-item execution, and OPAC2Floats re-types the output for compatibility with Mel's popular mtb node pack if you have that installed). Reach for OPAC any time you want a pan, zoom, or rotate animation that feels organic rather than mechanically linear, without typing out a Deforum-style schedule string by hand.

Installing it

ComfyUI Manager: search SaltAI-Open-Resources. Manual install:

cd ComfyUI/custom_nodes
git clone https://github.com/get-salt-AI/SaltAI

Restart ComfyUI. No model downloads - this is procedural noise generation, not a neural network.

Common issues

The range fields are plain "min,max" strings, not two separate number fields - a malformed string (missing comma, extra spaces in the wrong place) will error rather than silently fall back to a default, so double-check the format if a range field misbehaves. If the motion feels too jittery or too calm, tremor_scale for that specific parameter is the first thing to adjust before touching the range itself - the range sets the bounds, the tremor scale sets how restlessly it moves inside them. If you want a smooth, deterministic, repeatable camera move instead of organic wandering, use_wiggle set to false is the toggle to try - a fixed, predictable schedule is a fundamentally different design goal than a natural one, and this node covers both. Keep frame_count consistent with whatever else in your graph is counting frames (an image batch length, another schedule feeding the same animation) - a mismatch there is a common source of a schedule that runs out before your actual sequence does, or vice versa.

CategorySALT/Animation/Keyframing

Inputs (19)

NameTypeDefaultDescription
use_wiggleBOOLEANtrue
frame_countINT481–500
zoom_rangeSTRING0.95,1.05
zoom_tremor_scaleFLOAT0.050.01–1
angle_rangeSTRING-5,5
angle_tremor_scaleFLOAT0.050.01–1
trx_rangeSTRING-10,10
trx_tremor_scaleFLOAT0.050.01–1
try_rangeSTRING-10,10
try_tremor_scaleFLOAT0.050.01–1
trz_rangeSTRING-10,10
trz_tremor_scaleFLOAT0.050.01–1
rotx_rangeSTRING-5,5
rotx_tremor_scaleFLOAT0.050.01–1
roty_rangeSTRING-5,5
roty_tremor_scaleFLOAT0.050.01–1
rotz_rangeSTRING-5,5
rotz_tremor_scaleFLOAT0.050.01–1
opac_perlin_settingsoptDICT

Outputs (8)

NameTypeDescription
zoomLIST
angleLIST
translation_xLIST
translation_yLIST
translation_zLIST
rotation_3d_xLIST
rotation_3d_yLIST
rotation_3d_zLIST