Atlas Director Take π¬
Pull a Director take back into the graph β nine sockets of camera move
- playblast
- rays
- rays_preview
- samples
- frame_count
- width
- height
- projected
- first_frame
Atlas Director is the pack's companion app: a place where you operate the camera against your solved scene - dolly, orbit, breathe the lens - the way a real camera operator would, instead of keyframing knots in a graph. Atlas Director Take π¬ is the node that brings what you shot back into ComfyUI as graph inputs. You hit the widget's "Launch Director" button, Director opens on a session, and when you finish a take it pushes the frames back to this node.
This is emphatically not a beginner's first Atlas node. It presupposes the companion app, configured and running, plus a scene you've already solved and exported. But when you're animating a still into an LTX camera move by actually flying the camera, it's the difference between operating and keyframing.
What comes back
Nine outputs, and they split into "the rendered thing" and "the data that describes it":
playblast- the rendered frames as a plainIMAGE. The grey flat-shaded guide of the take.rays- the full-precision six-channel PlΓΌcker embedding on its ownATLAS_RAYSsocket type. This is the one ComfyUI refuses to wire into an ordinary image node, deliberately: directions span [β1, 1] but moments are unbounded, and anIMAGEtensor is clamped to [0, 1], so one careless 8-bit hop would cost roughly half a degree of angular error. Don't fight the type system here - it's protecting you.rays_preview- a display-only three-channel version. The moment isn't represented at all; wire it only into a preview widget.samples- the raw per-frame camera samples for the rendered range, taggedATLAS_CAMERA.frame_count,width,height- the batch's real shape, read off the rendered frames on disk.projected- the same marked span asplayblast, but with the plate projected onto the geometry rather than the grey guide. Loaded through the identical code path so the two batches can't diverge in dtype or channel order.first_frame-projected's frame 0 as a batch of one: the photoreal IN-point. It's a dedicated output on purpose - the video model's contract wants exactly one frame, and an operator-wired "index 0" slice is a mistake waiting to happen.
The widget-versus-output trap
The width, height, frames and fps widgets at the top are launch targets only - the timebase pushed to Director before any take exists, used for drawing frame-lines. They are not a description of what you'll get. The real shape comes off the width/height/frame_count outputs, derived from the frames on disk, and a mismatch between widget and rendered take is normal, not an error. The frames widget even enforces LTX's rule that frame counts satisfy n % 8 == 1 (1, 9, 17, ... 121 ...), so frame-lines land on valid marks. colour_lane picks png (default, 8-bit playblast) or exr (the float colour lane) - it refuses loudly on a mismatch rather than silently reading the wrong lane.
Installing and the Director seam
The node ships in atlas-camera:
cd <ComfyUI>/custom_nodes
git clone https://github.com/mikejamesvfx/atlas-camera.git
Restart, and find "Launch Director" on the node's widget. The launch itself needs the Director executable configured via the ATLAS_DIRECTOR_BIN environment variable - without it the button explains exactly that and refuses, rather than launching nothing. There's real security posture in this seam (the route validates every path and session id, refuses rather than sanitises), so keep the variable pointing at a Director you actually trust.
The gotchas that look like bugs
A stale take is a hard refusal, never a warning - the node errors rather than read frames that don't correspond to the current session. Re-push from Director. Delivery address: Director pushes takes to your ComfyUI at http://127.0.0.1:8188 by default; if yours runs elsewhere, set ATLAS_COMFY_URL in ComfyUI's environment before launching, because a misconfigured address is silent - the launch succeeds with nowhere for the take to land. And projected is refused (naming the take as needing a re-push) when its sidecar or frame count disagrees with playblast's, because a projected batch that doesn't line up frame-for-frame with the grey guide looks usable and is silently misaligned - worse than none.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| session_id | STRING | shot_001 | The session id Director was launched with. Launching happens on a widget button outside execution -- this node only reads what a director already pushed for it. |
| width | INT | 76816β4096 | Launch target only: part of the timebase pushed to Director before any take exists, for drawing frame-lines. NOT the rendered playblast's actual pixel width -- read that off this node's `width` OUTPUT, derived from the first rendered frame. A mismatch between this widget and the rendered take is normal, not an error. |
| height | INT | 51216β4096 | Launch target only: part of the timebase pushed to Director before any take exists, for drawing frame-lines. NOT the rendered playblast's actual pixel height -- read that off this node's `height` OUTPUT, derived from the first rendered frame. A mismatch between this widget and the rendered take is normal, not an error. |
| frames | INT | 1211β4096 | Launch target only: part of the timebase pushed to Director before any take exists, for drawing frame-lines. NOT a description of the rendered take -- read the actual rendered length off this node's `frame_count` OUTPUT, derived from the frame files on disk (see `frame_files`). A take marked to a different length than this widget is normal, not an error. LTX only accepts frame counts n where n % 8 == 1 (1, 9, 17, 25, ..., 121, 129, ...) -- enforced on this widget too, so frame-lines land on valid marks; `read()` separately refuses, naming the nearest valid counts, when the RENDERED count violates this rule -- see `_ensure_frame_count_is_ltx_valid`. |
| fps | INT | 241β120 | Launch target only: part of the timebase pushed to Director before any take exists. This node has no per-frame timing to derive an actual fps from, so there is no `fps` output -- unlike width/height/frames, this widget has nothing on the take to disagree with. |
| colour_lane | COMBO | png (default): the 8-bit playblast frames. exr: the float colour lane, when the take actually carries one -- read as data, no divide-by-255, no colour convert. Refuses loudly on a mismatch rather than silently reading the wrong lane. |
Outputs (9)
| Name | Type | Description |
|---|---|---|
| playblast | IMAGE | β |
| rays | ATLAS_RAYS | β |
| rays_preview | IMAGE | β |
| samples | ATLAS_CAMERA | β |
| frame_count | INT | β |
| width | INT | β |
| height | INT | β |
| projected | IMAGE | β |
| first_frame | IMAGE | β |