Zura V3 · Pick camera angles
Plan Nine Camera Angles, Then Shoot the Clip You Planned
- source_frames
- stage
- candidate_1
- candidate_2
- candidate_3
- candidate_4
- candidate_5
- candidate_6
- candidate_7
- candidate_8
- candidate_9
- shot_plan
- contact_sheet
- stage
Every multi-camera workflow I've seen dies at the same place: the camera decisions live in your head, and the graph can't see them. You generate nine angle stills, then eyeball which one goes where across a two-minute clip, then try to remember. Zura V3 · Pick camera angles is the node that fixes that - it turns a 3×3 grid of candidate angles into a clickable gallery with a per-shot timeline, and it writes a shot plan the render nodes read.
It's the front door of the pack's V3 multicam flow. Not a generator itself; a planner and a filing cabinet.
What the nine angles are
The grid is camera side by framing: Left / Front / Right across, wide / medium / close down. Those are azimuths of −30°, 0° and +30°, with three "distance" planes. The author's own comment in the source is worth knowing before you build expectations: the comment in multicam_v3.py says CrossView's current LoRA does not follow distance reliably, so shot size is a visual proposal rather than a dolly command. The close row gets its shot size from a native crop downstream, not from asking the model to zoom.
Which means: you feed this node nine images. Where they come from is your business - a multi-angle LoRA on an image editor, a depth-warp guide, whatever you already trust. The node's job starts after that.
Inputs you actually set
source_frames- the trimmed 24 fps source clip, decoded frames. Everything is measured against these.frames_per_shot- default 24, one second at 24 fps. Range 12–3600. This sets how many shots the plan contains:ceil(frames / frames_per_shot), capped at 60.shot_choices- a comma list of angle numbers, one per shot,0meaning the original camera. The default0,6,0,4is a four-shot example.project_name- defaultperformance-v3. Sanitised to letters, digits,_and-, then truncated at 48 characters.stage- comes from Zura V3 · Choose pass. In pass 1 the node demands all ninecandidate_1…candidate_9images via ComfyUI's lazy-input mechanism, so nine generations actually run. In pass 2 it doesn't want them at all.shot_prompts- a JSON list of strings, one per shot. Only meaningful on generated-angle shots; a prompt on an original-camera shot is an error downstream.- Optional
look_prompt/look_enabled- a hash of the look is stored in the manifest, so changing your studio prompt invalidates the saved previews.
Outputs are shot_plan (the JSON - wire it into the H3 render node's shot_plan and into the V4 clean node), contact_sheet (a 960×645 labelled grid, perfect for Preview Image), and stage (pass the stage back out to other V3 nodes rather than daisy-chaining switches).
How it works
The planning pass writes a folder under ComfyUI/output/zura_multicam_v3/<project>/<signature>/ containing source.png, angle_1.png…angle_9.png and a manifest.json. The signature is a 16-hex digest over the frame shape plus sampled pixels from the first, middle and last frames - so it's specific to that exact clip, and re-trimming the source invalidates every saved angle. That's deliberate, and it's the single most common error you'll hit (The source changed after angle planning. Re-run Plan angles.).
The gallery UI is the good part: click a tile, then click a shot in the timeline. Clicking a camera saves your selection, it does not queue a render - the author calls that out in the UI itself, presumably after someone filed a bug.
Install
ComfyUI Manager → search Zura Nodes (publisher zuravfx), or:
cd ComfyUI/custom_nodes
git clone https://github.com/ZURAVFX/ComfyUI_zura_nodes
pip install -r ComfyUI_zura_nodes/requirements.txt
Restart ComfyUI. ffmpeg and ffprobe need to be on PATH for the pack's video handling. It's AGPL-3.0-only and ships no model weights - your H3 / Klein / Wan models and LoRAs are yours to place.
Where people get burned
shot_choices has to have exactly as many entries as the clip has shots. In planning mode the node is forgiving and fills the gaps with 0s; in the render pass it just fails. If you changed frames_per_shot after picking angles, you have more or fewer shots than choices and the plan no longer describes your clip.
And the honest limit from the README: a structurally valid graph is not visual sign-off. Plan a short clip, render it, and look at the joins before you put an hour of footage through it.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| source_frames | IMAGE | — | |
| stage | ZURA_MULTICAM_STAGE | — | |
| project_name | STRING | performance-v3 | — |
| frames_per_shot | INT | 2412–3600 | — |
| shot_choices | STRING | 0,6,0,4 | — |
| shot_prompts | STRING | [] | — |
| candidate_1opt | IMAGE | — | |
| candidate_2opt | IMAGE | — | |
| candidate_3opt | IMAGE | — | |
| candidate_4opt | IMAGE | — | |
| candidate_5opt | IMAGE | — | |
| candidate_6opt | IMAGE | — | |
| candidate_7opt | IMAGE | — | |
| candidate_8opt | IMAGE | — | |
| candidate_9opt | IMAGE | — | |
| look_promptopt | STRING | — | |
| look_enabledopt | BOOLEAN | false | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| shot_plan | STRING | — |
| contact_sheet | IMAGE | — |
| stage | ZURA_MULTICAM_STAGE | — |