Atlas Disocclusion Guide π£
Show a video model exactly what it must invent
- solve
- source_image
- camera_path
- exclude_mask
- guide
- hole_mask
- report
Every projection pipeline hits the same wall: you move the camera, and the geometry stops covering parts of the frame. Those revealed regions are called disocclusion holes, and they're the reason a still plate can look perfect and a dolly move looks like it's tearing. AtlasDisocclusionGuide doesn't fill those holes - it shows a video model exactly where they are, by rendering the move and painting every uncovered pixel in an out-of-gamut sentinel colour.
Think of it as the bridge between the pack's still-frame world (clean plates, inpaint, cards) and the generative-fill world (LTX, WAN, any video model). The pack's own docs put it plainly: a single still-frame fill can't serve a camera move without flicker, so the guide produces a conditioning signal instead. And because it renders the whole move, the output is literally an IMAGE batch with one frame per path sample - ready to feed a video model directly.
How it works
It runs the camera path through the same z-buffered rasterizer the pack uses for its stereo rendering, and every pixel no projection mesh covers gets painted with the sentinel colour. Default sentinel is magenta, and the tooltip tells you exactly why: it's what the LTX-2 CrossView-Warp IC-LoRA expects. Avoid black unless a consumer demands it - the tooltip's warning is perfect: real plates contain black, so it's indistinguishable from content. chroma_green is the other option.
Two controls shape the result:
hole_dilate_px- a z-buffered render leaves thin one-pixel seams along silhouettes; a few pixels turns that speckle into coherent blobs, which generative fillers handle far better. Dilation only ever marks more as unseen, so it can't invent coverage.resolution(default 1024) - long edge. The tooltip's warning is worth heeding: the rasterizer is pure-NumPy and costs O(faces Γ pixels), and it renders every path frame. Keep it moderate for long moves on dense relief meshes.
And the clever one: last_n. The single-frame fill doctrine only ever consumes the end of a move - the final frame's holes are a superset of every earlier frame's. So rendering a 100-frame arc to use 5 frames is pure waste. last_n=1 (final frame) or 5 (a WAN 4k+1 window) cuts render time and memory by the path length. Batch indices become relative to the window.
The other inputs
Required: solve and source_image. Then:
camera_path- the move to render. Without it you get a single sanity frame from the solved camera, which by definition has almost no holes. Wire a baked path from the viewport's Camera Path mode and the output becomes the video-model feed.exclude_mask- regions already handled by something other than geometry (typically sky carried by a matte or SkyDome). Excluded pixels aren't marked and are left out of the coverage figure - so the guide won't ask the model to invent a sky you're already handling.
Outputs: guide (the IMAGE batch), hole_mask (a MASK batch), and report, which splits move-revealed disocclusion from regions the geometry never covered - different problems, and only the first is a filler's job.
Install
cd <ComfyUI>/custom_nodes
git clone https://github.com/mikejamesvfx/atlas-camera.git
Restart (or Manager β "atlas-camera"). Needs the [neural] tier for depth/geometry upstream. The kornia <0.8.3 cap protects LTXVideo; GeoCalib from GitHub. It's a brand-new pack with no community folklore, so the two habits to take from the docs are: keep resolution moderate, and set last_n once you trust the end-of-move doctrine.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| solve | ATLAS_SOLVE | β | |
| source_image | IMAGE | β | |
| camera_pathopt | ATLAS_CAMERA_PATH | The move to render. Every sampled frame becomes one image in the output batch, so this feeds a video model directly. Without it you get one frame from the solved camera itself, which by definition has almost no holes β useful only as a sanity check. | |
| sentinelopt | COMBO | magenta | Colour for pixels the source camera never saw. Magenta is what the LTX-2 CrossView-Warp IC-LoRA expects. Avoid black unless a consumer demands it: real plates contain black, so it is indistinguishable from content. |
| hole_dilate_pxopt | INT | 00β64 | Grow the marked region. A z-buffered render leaves thin one-pixel seams along silhouettes; a few px turns that speckle into coherent blobs, which generative fillers handle far better. Dilation only ever marks MORE as unseen, so it can never invent coverage. |
| resolutionopt | INT | 1024256β4096 | Long edge. The pure-numpy rasterizer is O(faces x pixels) and this renders EVERY path frame β keep it moderate for long moves on dense relief meshes. |
| exclude_maskopt | MASK | Region already handled by something other than geometry β typically sky carried by a matte or a SkyDome. Excluded pixels are NOT marked and are left out of the coverage figure entirely. Without this, sky with no geometry behind it reads as a permanent hole, so the guide tells the model to invent a sky that is already being handled. | |
| last_nopt | INT | 00β4096 | Render only the move's LAST N frames (0 = every frame). The single-frame fill doctrine only ever consumes the END of the move (its holes are a superset of every earlier frame's), so rendering a 100-frame arc to use 1-5 frames is pure waste β last_n=1 (final frame) or 5 (a WAN 4k+1 window) cuts render time and memory by the path length. Batch indices become RELATIVE to the window: final frame = last_n-1. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| guide | IMAGE | β |
| hole_mask | MASK | β |
| report | STRING | β |