Parallax Motion Camera Scheduler
Generate a multi-layer parallax camera move for ComfyUI animation
- float_layers
This is the node behind Salt AI's own launch demo - when the team behind this pack announced their platform in March 2024, the flagship example was "a new text2vid workflow featuring parallax motion." Parallax Motion Camera Scheduler is that engine: point it at how many frames you want and it generates a full per-frame camera move - panning, zooming, and organic tremor - across multiple depth layers at once.
How it works
The core trick is layer_offsets, a comma string like "1,0.8,0.6". Each depth layer moves at a different fraction of the base camera speed - 1.0 for your foreground layer, 0.8 and 0.6 for progressively farther-back layers. That's the classic multiplane camera technique: near things move more than far things, and that speed difference alone is what sells depth on a flat, layered image, no actual 3D geometry required. It's a different approach from depth-map-based parallax tools like DepthFlow, which warp a single image along a computed depth map instead - this node assumes you've already split your scene into layers and just needs to know how to move each one.
On top of the pan/zoom motion, tremor_scale, tremor_octaves, tremor_persistence, and tremor_lacunarity add Perlin-noise camera shake for a hand-held feel, and direction_curve applies an easing curve (linear through several bounce and sinusoidal options) to smooth the transitions when the pan direction changes.
The inputs and outputs that matter
frame_count(default 60) - match this to your actual clip length.pan_directions(STRING, e.g."90,180,270") anddirection_change_frames(STRING, e.g."10,20,40") - read together: pan toward 90° until frame 10, then 180° until frame 20, then 270° until frame 40. These two strings need matching entry counts, and nothing validates that for you until runtime.zoom_mode(enum: zoom-in / zoom-out / zoom-in-out) pluszoom_speed- the push/pull behavior.layer_offsets- how many layers you're compositing and how separated they should feel.
Output is one packed float_layers LIST covering every layer at once - not directly usable per layer on its own. That's what OPCSLayerExtractor is for.
How to install it
ComfyUI Manager: search SaltAI-Open-Resources or SaltAI, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/get-salt-AI/SaltAI
then restart. No model download, no heavy dependency - it's schedule generation, all math.
Common issues & troubleshooting
Camera path looks wrong or truncates early. Almost always a mismatch between pan_directions and direction_change_frames - a stray extra comma or a missing entry in either free-text string, and there's no schema validation to catch it before you queue the run.
Tremor feels wildly different from OPACListVariance's tremor. Don't copy settings between the two expecting the same feel - this node's tremor_scale tops out at 1024, while OPACListVariance's tops out at 1. They're on different scales (this one's closer to raw pixel/coordinate units), not a bug in either.
Output does nothing downstream. float_layers is packed for all layers together - plug it straight into an OPCSLayerExtractor per layer rather than trying to feed it directly into something expecting a single per-frame value list.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| frame_count | INT | 601–4096 | — |
| zoom_speed | FLOAT | 0.0100.001–1 | — |
| pan_speed | FLOAT | 0.5000.001–5 | — |
| pan_directions | STRING | 90,180,270 | — |
| direction_change_frames | STRING | 10,20,40 | — |
| tremor_scale | FLOAT | 64.000.01–1024 | — |
| tremor_octaves | INT | 11–10 | — |
| tremor_persistence | FLOAT | 0.500.01–1 | — |
| tremor_lacunarity | FLOAT | 2.001–3 | — |
| direction_curve | COMBO | 10 options: linear, ease-in, ease-out, ease-in-out, bounce-in, bounce-out, +4 | |
| start_x | FLOAT | 0.00-16384–16384 | — |
| start_y | FLOAT | 0.00 | — |
| zoom_mode | COMBO | 3 options: zoom-in, zoom-out, zoom-in-out | |
| layer_offsets | STRING | 1,0.8,0.6 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| float_layers | LIST | — |