Atlas Sky Dome Layer ☁
Atlas Sky Dome Layer ☁ — the classic DMP sky card, done properly
- solve
- depth
- sky_mask
- plate_image
- plate_ref
- solve
- hole_mask
- extend_mask
- report
AtlasSkyDomeLayer is the node that separates the sky from everything else and projects it onto a simple constant-depth card instead of a depth-following relief mesh. That's the standard digital matte painting move - the same one Nuke artists have used for decades - and it exists because sky depth from monocular models is noisy and meaningless. There's no real "depth" to a sky; it's just wherever the segmentation mask ends. Fighting that with geometry is a waste, so this node doesn't: the sky_mask is the sole authority on the layer's shape, and real depth values are never read for the card's geometry.
The workflow the README describes is honest about where the clean sky comes from: invert the sky mask, run the original photo through an external inpaint chain (INPAINT_ExpandMask → INPAINT_InpaintWithModel or similar - LaMa-style), and wire the result in as plate_image. This node doesn't invent sky pixels; it places the clean sky you already made onto the dome. The mask decides what's sky, the dome decides where it sits.
Inputs that matter
- solve, depth, sky_mask, plate_image - the required quartet.
depthis required but only used for context - the card's shape ignores it, which is the whole point. - radius_m vs distance_m - the two modes, and the fiddliest part. With
distance_mat 0 (legacy):radius_mis the card's distance in metres, and it should comfortably exceed the scene's own backdrop distance so the card never intersects real geometry. Withdistance_mset:radius_mbecomes the card's minimum half-extent - its size - and the card grows (never shrinks below frustum coverage) via extra outpaint until it reaches that world size. Distance drives parallax; size drives orbit/pan slack. Read that tooltip twice; it's the difference between a dome that hides its edge and one that doesn't. - edge_extend_px - the Nuke premult→dilate trick: smear the sky's edge colours a few dozen pixels past the silhouette and overhang the dome mesh, so a small orbit reveals plausible gradient sky instead of black slivers. 0 = off.
- frame_outpaint_px - same deterministic trick, but past the frame edges, so a small pan doesn't slam into the plate boundary. The sky source gets its own enlarged canvas and widened intrinsics; the primary solve is untouched.
- relief_grid, name, priority - mesh density (96 default is plenty for a flat card), the layer name, and blend priority (default −10, low, since the mask makes it spatially exclusive anyway).
Outputs: the updated solve, hole_mask, extend_mask (where it overhung), and a report.
The gotcha worth remembering
This is the honest part of the pack: a flat dome with dilated edges covers narrow disocclusions of smooth sky beautifully, and it will not save you on large structured reveals - clouds popping out from behind a building still need a real LaMa/inpaint chain on the plate. Don't blame the dome for a job it was never meant to do.
Install
The node itself is core, but it needs a solve, a depth map (the [neural] tier - torch + GeoCalib + Depth Anything V2, or the MoGe/DA3 backends), and a real sky mask from AtlasSAM3Mask ([sam3]):
cd <ComfyUI>/custom_nodes
git clone https://github.com/mikejamesvfx/atlas-camera.git
Restart, or install the pack via ComfyUI Manager ("atlas-camera"). It's under Atlas/07 · Clean Plate & Inpaint. First run will download the depth model weights - that's the slow bit, not the install.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| solve | ATLAS_SOLVE | — | |
| depth | ATLAS_DEPTH_MAP | — | |
| sky_mask | MASK | Real segmentation marking sky pixels (e.g. ComfyUI-RMBG's SAM3 Segmentation prompted with 'sky'). Sole authority on this layer's shape — real depth values are never read for the card's geometry. | |
| plate_image | IMAGE | A CLEAN sky plate — invert sky_mask, run it through an external inpaint chain (INPAINT_ExpandMask -> INPAINT_InpaintWithModel) on the original photo, wire the result here. | |
| radius_mopt | FLOAT | 3001–100000 | With distance_m at 0 (default): the card's DISTANCE in metres (forward-Z, legacy behavior) — should comfortably exceed the scene's own derived backdrop distance so it never intersects real geometry. With distance_m set: the card's minimum half-extent — its SIZE, radius in the dome sense — the card is enlarged (never shrunk below frustum coverage) via extra outpaint so it reaches this world size at that distance. Distance doesn't affect appearance from the solve camera (texel assignment is by ray); it controls parallax — how far you can dolly/orbit before the card reveals itself. |
| relief_gridopt | INT | 9616–4096 | Card mesh density (long-edge grid columns). A flat, constant-depth card needs far less density than real geometry — default is lower than AtlasDeriveReliefMesh's. |
| nameopt | STRING | sky | — |
| priorityopt | FLOAT | -10-100–100 | Blend priority among layers (higher wins). Low by default since sky_mask makes this layer spatially exclusive from ground/foreground layers in practice. |
| plate_refopt | ATLAS_PLATE_REF | Optional registered final clean-plate reference. Browser still uses image_b64 preview; exporters use this for EXR/float-safe handoff. | |
| edge_extend_pxopt | INT | 480–512 | Deterministic edge-extend (the classic Nuke premult->dilate trick, NOT an inpaint): smears the sky's edge colors this many pixels past the silhouette into the plate, dilates the matte to match, and overhangs the dome mesh accordingly - so orbiting reveals plausible gradient sky behind foreground silhouettes instead of black slivers. Enough for narrow disocclusions of smooth sky; large structured reveals (clouds behind a building) still want a real LaMa/inpaint chain on plate_image. 0 = off. |
| frame_outpaint_pxopt | INT | 640–1024 | Outpaint the sky past the FRAME edges by this many pixels (edge-replicated then smeared, same deterministic trick as edge_extend_px) so a small orbit/pan doesn't slam into the plate boundary. The sky source gets its own enlarged canvas + widened intrinsics (cx/cy shifted, W/H grown), and the dome mesh extends past the original frustum to carry it. Purely this layer's camera - the primary solve and every other layer are untouched. 0 = off. |
| distance_mopt | FLOAT | 00–100000 | Card distance from the camera in metres. 0 (default) = legacy behavior: radius_m IS the distance and size follows from the frustum. When set, this places the card and radius_m becomes its minimum half-extent (SIZE): if the frustum footprint at this distance is smaller than radius_m, the card grows via extra outpaint (edge-replicated pixels, declared in extend_mask; total padding memory-capped at half the plate's long edge per side). Distance = parallax; size = orbit/pan slack. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| solve | ATLAS_SOLVE | — |
| hole_mask | MASK | — |
| extend_mask | MASK | — |
| report | STRING | — |