Atlas Viewport π§
The browser 3D view that turns a photo into a scene
- solve
- source_image
- primary_depth
- controls
- shot_cam
- output_profile
- debug_matte
- patch_mask
- clean_plate
- shaded
- depth
- normal
- mask
- path_frames
- camera_path
- patch_azimuth_view
- patch_elevation_view
- patch_distance
- patch_prompt
- patch_exact
- patch_render_mask
- solve
- drawn_mask
- draw_report
Atlas Viewport π§ (class AtlasBlockoutViewport) is the node you'll spend the most time staring at. It opens a real-time 3D viewport in the ComfyUI browser, pre-aligned to your recovered camera, so you can actually look through the scene before you export it. It's the pack's review room, blockout tool, camera-path author, and angle-extractor all in one node.
What it does
The pattern mirrors the Yedp Blockout approach: the browser renders, sends base64 JSON to Python, Python decodes it, and out come proxy image outputs. Concretely:
- Connect an
ATLAS_SOLVEandsource_image, queue once. - The Three.js viewport opens, camera locked to the photo.
- Place primitive geometry - box, plane, person card - to block out the scene.
- Click Render Proxy Passes; it fills
client_dataand re-queues. - Four proxy/LDR outputs come alive:
shaded,depth,normal,mask- wire them into ControlNet or compositing.
resolution sets the long-edge render size (128β8192, default 1024); the short side auto-follows your source image's aspect. You can also drag the node's resize handle. A shot_cam from AtlasDefineShotCam conforms it to a project format instead.
The two features that make it the hub
Camera Path mode. Author a keyframed move in the viewport. "βΊ Bake Full Path" produces path_frames (a proxy image batch - feed it to repair preview or Video Combine) plus camera_path (the raw keyframes, feed it to AtlasExportCameraPathUSD for a real animated camera). "π· Bake Repair Frame" stores only the final preview frame for path-guided repair. Frames outside the recovered camera's cone show the documented black/undefined regions - expected, not a bug.
Extract Angle π. This is the multi-angle patch workflow's best friend. Orbit to the view you want a patch generated at, click π, and the node measures the orbit delta from the recovered camera, snaps it to the Qwen Multiple-Angles LoRA's nearest named views, and outputs four strings: patch_azimuth_view, patch_elevation_view, patch_distance (wire into AtlasAddPatchView's widgets) and patch_prompt (the ready-to-use <sks> [azimuth] [elevation] [distance] LoRA prompt). The delta uses the same pivot the backend uses, so the snapped views round-trip exactly. Until you extract an angle these outputs return an ExecutionBlocker - downstream branches stay paused rather than wasting a generation on a zero-orbit patch.
What else is under the hood
preview_expand dilates geometry for wider orbit coverage - leave it at 1.0 if you use Project mode, or the dilated fringe has no real photo data and renders black. clean_plate projects a background plate through the same registered projector so tears reveal a clean backdrop. drawn_fill_px (default 96) fills drawn shapes by smearing surrounding plate colors - deterministic edge-extend, not an inpaint; set 0 and route drawn_mask to a real inpaint if you prefer. primary_depth powers the ray-traced occlusion-culling (β Occlude) toggle. And if the node feels cramped, connect an AtlasViewportControls node to controls to move every button and panel off this one - the link carries no data, it just lets the two frontends find each other.
The node outputs a lot: the four proxy passes, path_frames, camera_path, the four patch strings, patch_render_mask, the pass-through solve, drawn_mask, and draw_report. It's an output node, so it renders even with nothing downstream.
Install is the pack's clone-and-go. The depth-dependent culling wants the [neural] extra, and heavy orbits want a GPU, but the core viewport runs on CPU fine.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| solve | ATLAS_SOLVE | β | |
| source_image | IMAGE | β | |
| resolution | INT | 1024128β8192 | Long-edge render resolution; the short side auto-follows the source image aspect (viewport inherits the image's aspect). Also settable by dragging the node's own resize handle. |
| client_data | STRING | β | |
| primary_depthopt | ATLAS_DEPTH_MAP | Optional depth map matching the source image AND the depth object used to derive the displayed relief mesh. Do not pair a DCC retopo preview regenerated with another depth model. Used by the viewport to power the ray-traced occlusion culling feature (β Occlude). | |
| preview_expandopt | FLOAT | 1.001β5 | Dilate derived geometry outward from the camera for wider orbit coverage before it disappears into unreconstructed space. 1.0 = off (accurate geometry). Display only β never affects DCC exports or measured geometry. CAUTION: values above 1.0 dilate geometry beyond what the camera actually photographed, so with π½ Project active the dilated fringe has no real photo data and renders as empty/black the moment you orbit off the exact recovered viewpoint β leave at 1.0 if you plan to use Project, raise it only for inspecting undressed blockout shapes. |
| controlsopt | ATLAS_VIEWPORT_LINK | Connect an AtlasViewportControls node here to move all buttons/panels off this node (perspective-only, freely resizable). Carries no real data β Python ignores it; the link only lets the two nodes' frontend JS find each other. | |
| shot_camopt | ATLAS_SHOT_CAM | Optional project/shot camera format (AtlasDefineShotCam) β conforms the render resolution/aspect and viewing-camera FOV to this format instead of auto-following source_image's own aspect. A direct wire here wins over one attached to `solve` by AtlasMergeGeometry. Never affects how the source photo is projected onto geometry. | |
| output_profileopt | ATLAS_OUTPUT_PROFILE | Optional OCIO-style output/profile metadata from AtlasViewportControls. Browser preview remains display-inferred/proxy; final fidelity belongs to OCIO Write, Nuke, Maya, or Resolve. | |
| debug_matteopt | MASK | π Optional debug isolate (e.g. a layer's SAM3 mask, source-image space): under π½ Project the viewport dims everything whose primary-camera projection falls OUTSIDE this matte (π toolbar toggle + dim slider; dim 0 = hard cull). Display-only β never affects exports, geometry, or the projection itself. | |
| patch_maskopt | MASK | Source-image-space created_islands mask from AtlasPlanarHolePatch. Under π¨ Layers the generated patches receive their own magenta identity color. Render Proxy Passes reprojects the same pixels from the current moved camera and returns patch_render_mask for inpainting. | |
| drawn_fill_pxopt | INT | 960β512 | Fill drawn surfaces (βοΈ Draw / β£ Box / β Sphere) by smearing the surrounding plate colours across their footprint, the same deterministic edge-extend the clean-plate path uses. They stand where the camera never saw, so the raw plate would paint them with whatever occluded them. 0 = off (leave the raw projection and route `drawn_mask` to a real inpaint instead). |
| clean_plateopt | IMAGE | Optional clean plate β the BACKGROUND layer of a layered composite: the projection_backdrop plane and any solve_b geometry merged in by AtlasMergeGeometry project THIS image, so tears in the foreground reveal the clean background through the same registered projector. Drawn/wand fills patch the foreground's own tears and keep the drawn_fill_px smear. | |
| auto_presetopt | COMBO | off | Author this camera-move preset and BAKE it when the node executes, instead of clicking π₯ Camera Path and βΊ Bake Full Path by hand. NEEDS A BROWSER with this graph open β the bake renders in Three.js, so a headless queue produces no frames however this is set. Baking re-queues the prompt, so the frontend fingerprints (solve, preset, frames, resolution) and re-bakes only when one changes; without that guard the re-queue would bake forever. |
| auto_framesopt | INT | 00β2048 | Frame count for auto_preset. 0 leaves the preset's own length (100) alone. LTX wants frames % 8 == 1 β 81, 97, 121 β and a count that violates it bakes fine here and is refused downstream. |
Outputs (15)
| Name | Type | Description |
|---|---|---|
| shaded | IMAGE | β |
| depth | IMAGE | β |
| normal | IMAGE | β |
| mask | IMAGE | β |
| path_frames | IMAGE | β |
| camera_path | ATLAS_CAMERA_PATH | β |
| patch_azimuth_view | STRING | β |
| patch_elevation_view | STRING | β |
| patch_distance | STRING | β |
| patch_prompt | STRING | β |
| patch_exact | STRING | β |
| patch_render_mask | MASK | β |
| solve | ATLAS_SOLVE | β |
| drawn_mask | MASK | β |
| draw_report | STRING | β |