Nodes/atlas-camera/Atlas Ground Plane 🟫
ComfyUI Node

Atlas Ground Plane 🟫

Place the ground by hand when the depth model is lying to you

By mikejamesvfxΒ·Created 2 months agoΒ·Updated a day agoΒ· 1
Atlas Ground Plane 🟫
  • solve
  • solve
  • report
β—„width_m40β–Ί
β—„depth_m40β–Ί
β—„offset_x0.0β–Ί
β—„offset_y0.00β–Ί
β—„offset_z0.0β–Ί
β—„tilt_deg0.0β–Ί
β—„roll_deg0.0β–Ί
β—„anchorsolve_ground_centreβ–Ί
β—„nameartist_groundβ–Ί

Atlas derives most of its ground plane from the depth map, and depth maps are great at shapes and bad at absolute scale. The pack's own experiment on a real street plate found the fitted plane tracked the observed road to Β±0.03 m inside 40 m - the fit was fine. The error that mattered was 48% of scale, from two depth models disagreeing about camera height. When the measurement is what's wrong, no amount of clever fitting fixes it; you want a ground the artist places directly. That's AtlasGroundPlane: one solve in, one honest, hand-placed plane out.

How it works

The node appends a normal projection_proxy plane primitive to your solve - nothing exotic. Because it's a regular primitive, it flows through every existing path: wire it into AtlasMergeGeometry next to your derived geometry, the viewport projects the plate onto it, AtlasRetopologizeLayer can retopologise it, and every exporter writes it out.

Two things it deliberately does not do, and both are the reason to trust it:

  • It never rotates the world. World +Y is the solve's gravity, so tilt_deg and roll_deg turn this plane's own transform - a tilted ground arrives in a DCC as one rotated object while every facade stays plumb. A ground that rotated the world would lean the whole scene.
  • It never claims to be measured. The primitive is tagged provenance="artist_placed" and trust="placeholder", so nothing downstream can promote your eyeballed placement into evidence. It's support geometry, honestly labelled.

The inputs that matter

Only solve is required. The useful knobs, in order of how often you'll touch them:

  • offset_y - this one is HEIGHT. 0 sits the plane on Y=0, which is where a scaled solve puts the ground. Nudge it when the plate says the road is higher or lower than the depth model measured it.
  • width_m / depth_m (both default 40) - extent along world X and Z in metres.
  • tilt_deg / roll_deg - rotate the plane itself (far edge lifts/drops, or banks left/right), clamped to Β±89Β°.
  • anchor - solve_ground_centre (default) puts the plane directly beneath the recovered camera on Y=0 so it lands in frame; world_origin is plain (0,0,0).
  • name - AtlasMergeGeometry doesn't de-duplicate names, so if you place more than one ground, give each its own; a clash on the same solve gets auto-suffixed anyway.

Outputs: the updated solve and a report (STRING) stating the plane's size, position, and - importantly - that it's tagged as support, not measurement.

Installing

Standard pack install, no extras for this one:

cd <ComfyUI>/custom_nodes
git clone https://github.com/mikejamesvfx/atlas-camera.git

or Manager search "atlas-camera", then restart. Pure Python, no GPU, no extra pip packages. It runs fine in the default core tier.

Where people get burned

  • The ground isn't where the road is - that's offset_y, almost always. The depth model measured the road's height wrong; raise or lower the plane until the projected plate lines up.
  • A tilted plane that leans the whole world - you can't get this by accident here, which is the point. If your scene looks leaning, it wasn't this node; check an orientation/gravity node instead.
  • Two grounds that look identical downstream - name collision. AtlasMergeGeometry won't tell them apart, so pick distinct names.

The honest framing: this is the node you reach for after a derived ground fails you, not before. Run the depth-derived version first, see where it's wrong, then replace or supplement it with one you placed. The label says it all - placeholder, not measurement.

CategoryAtlas/05 Β· Geometry

Inputs (10)

NameTypeDefaultDescription
solveATLAS_SOLVEβ€”
width_moptFLOAT400.01–100000Extent along world X, in metres.
depth_moptFLOAT400.01–100000Extent along world Z, in metres.
offset_xoptFLOAT0.0-100000–100000Shift along world X from the anchor.
offset_yoptFLOAT0.00-100000–100000HEIGHT. Raises or lowers the plane. 0 sits it on Y=0, which is where a scaled solve puts the ground. Nudge this when the plate says the road is higher or lower than the depth model measured it.
offset_zoptFLOAT0.0-100000–100000Shift along world Z from the anchor. Negative pushes the plane away from a camera facing world -Z.
tilt_degoptFLOAT0.0-89–89Rotate about world X: the far edge lifts or drops. Turns THIS PLANE only, never the world.
roll_degoptFLOAT0.0-89–89Rotate about world Z: the plane banks left or right. Turns THIS PLANE only, never the world.
anchoroptCOMBOsolve_ground_centreWhere the offsets are measured from. solve_ground_centre puts the plane directly beneath the recovered camera on Y=0, so it lands in frame; world_origin is plain (0, 0, 0).
nameoptSTRINGartist_groundPrimitive name. AtlasMergeGeometry does not de-duplicate names, so give each ground its own if you place more than one; a clash on the same solve is auto-suffixed.

Outputs (2)

NameTypeDescription
solveATLAS_SOLVEβ€”
reportSTRINGβ€”