Atlas Horizon / Sky Mask
A sky mask from the solved horizon line, not from guessing
- solve
- MASK
AtlasHorizonMask gives you a clean sky/ground mask without running any segmentation model - it just reads the horizon line that the camera solve already recovered and turns it into a mask. In the atlas-camera world the solve doesn't stop at "a camera exists"; it also recovers the horizon as a line in the image (in ax + by + c = 0 form). This node evaluates that line across the frame: everything above it is sky, everything below is ground. 1 = above horizon, 0 = below. Done.
What makes it worth reaching for over a semantic segmenter is that it's geometric - it inherits the camera's orientation, so it stays exactly consistent with the projection you're building. A segmentation model can hand you a "sky" mask that disagrees with where the recovered camera thinks the horizon is, and in a projection pipeline those disagreements turn into visible seams when the plate moves. This mask can't disagree with the solve, because it is the solve.
How it works
The node takes the solve's horizon_line and evaluates the signed line equation across a grid at your requested size. Positive signed distance is above the horizon (sky); it flips the mask accordingly. There's no machine learning in the loop - it's pure arithmetic, instant, and it runs on nothing.
If the solve carries no horizon line at all, the node degrades to a full-image sky mask (all ones) rather than erroring. That's a fallback, not a result: it means the solver didn't find a horizon on your frame, which usually happens with extremely level or extremely steep camera angles.
The inputs
solve is required. Then:
image_width/image_height- 0 (the default) adopts the source image size automatically. Set them explicitly if you want a mask at a different resolution than the plate.feather_px- Gaussian feather around the horizon edge, in pixels. 0 = hard cut. A small feather (8–16) is usually worth it if the mask feeds anything that composites, since a razor edge right on the horizon line reads as a line.
The single output is the MASK. Wire it into anything that wants a sky region - feeding a sky card's clean plate, excluding sky from a relief mesh's depth triangulation, or just isolating ground.
Install and gotchas
Ships with the pack. Install once via ComfyUI Manager (search atlas-camera) or git clone https://github.com/mikejamesvfx/atlas-camera.git into custom_nodes, then restart. No extra dependencies, no GPU, no model downloads.
Two gotchas worth knowing. First, the mask is a straight line split - real horizons are often occluded by buildings, hills or foreground, and this node will happily call a skyscraper "sky." If your plate has anything crossing the horizon, pair this with a segmentation mask rather than trusting it alone. Second, the feather is applied in pixel space perpendicular to the line, so at shallow horizon angles (near-flat ground perspective) the feathered band covers more scene than you might expect - dial feather_px down for those.
It's a small, deterministic utility. When you need "everything above the solved horizon" and you want it to agree with the camera, this is the fastest way to get it.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| solve | ATLAS_SOLVE | — | |
| image_width | INT | 00–8192 | 0 = auto (adopt source image width) |
| image_height | INT | 00–8192 | 0 = auto (adopt source image height) |
| feather_px | INT | 00–200 | Gaussian feather in pixels around horizon edge |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | — |