Atlas Scene To 3D π§
The whole projection stack as one GLB ComfyUI can just open
- solve
- source_image
- project
- model_3d
- model_3d_info
- camera_info
- glb_path
- report
Atlas spent four hundred lines of this workflow solving a camera and building a layered projection scene. Eventually you want to look at it in 3D without opening Maya. Atlas Scene To 3D π§ writes the whole layered scene as one GLB plus the recovered camera, in ComfyUI's own native 3D socket types, so you can wire the outputs straight into Save 3D (Advanced) or Preview 3D (Advanced) and orbit the thing in the graph.
That's a quieter win than it sounds. The 3D corner of this ecosystem is famously install-hostile - the community's most-upvoted 3D threads are about escaping compiled CUDA packs, not about the models. Using the core Load3D/Preview3D tier and skipping ComfyUI-3D-Pack entirely is the right call for this job.
It also answers the honest objection you get whenever someone asks for a camera-projection workflow in a ComfyUI community: that ComfyUI isn't the whole pipeline, and the modelling, comp and delivery happen somewhere else. Fair. So this node is deliberately a handoff rather than a renderer - the graph does the solve and the layers, and the scene lands in a format the rest of your pipeline already eats. You're going to end up in a DCC anyway; this way you're not rebuilding the geometry when you get there.
What lands in the GLB
One GLB carrying every projection layer as its own unlit textured mesh: the relief, generated objects (with their vertex-colour hidden side), clean-plate bands, sky domes. Analytic planes are skipped. Each layer is painted with its own full-resolution PNG plate - the sources use their image_b64, which is exactly what projects, outpaint and edge-extend included.
glTF has no EXR image type, so with write_exr on, each plate is also written as a half-float EXR sidecar, named in its material's extras. That sidecar is scene-referred only if the layer had a float plate_ref; otherwise it's a linearised display plate and the report says which. Read that line before you comp anything.
camera_info is the recovered solve camera: vertical FOV, aspect, ground pivot target, in the same Y-up/βZ convention Load3D uses, with no conversion. model_3d_info is identity.
Inputs and outputs
Required: solve, source_image (full-res primary plate - paints the primary relief and the generated objects).
Optional: write_exr (true); filename_prefix (atlas/scene); max_glb_mb (1024 - a GLB over budget is refused, naming its measured size, before any file is written; 0 disables the budget, and values past the GLB format's 4 GiB limit are clamped to it); project (an AtlasProject, which drops the GLB, every EXR/PLY sidecar and the manifest together into the shot's geo/ lane, superseding the prefix's folder); hdr_plate_path (default empty - an optional HDR plate EXR of the SAME photo, i.e. the matrixZone still workflow's ACEScg output, written as the primary layer's EXR sidecar instead of the linearised display plate; it must match the source image's size; the GLB's embedded texture stays the display PNG because glTF has no float textures).
Same file-watching caveat as elsewhere in this pack: a typed hdr_plate_path re-runs the node when the file changes on disk, a linked one only re-runs when the upstream node does, because ComfyUI doesn't pass linked values to IS_CHANGED.
Outputs: model_3d (FILE_3D_GLB), model_3d_info (LOAD3D_MODEL_INFO), camera_info (LOAD3D_CAMERA), glb_path, report. Writing happens on queue.
Install
cd <ComfyUI>/custom_nodes
git clone https://github.com/mikejamesvfx/atlas-camera.git
Or ComfyUI Manager β atlas-camera (ComfyUI Registry). Restart.
Two requirements worth stating plainly:
- ComfyUI V135 or later. The
FILE_3D_GLBandLOAD3D_*socket types are core ComfyUI types, not Atlas's; on anything older the node's outputs have nowhere to plug in. This is the single most common reason this node "doesn't work". - OpenImageIO if you want the EXR sidecars - the
[oiio]extra. Without it you get the GLB and the PNG plates, which is often fine for review.
The Pixal3D lane behind generated objects needs its four model files (models/diffusion_models/pixal3D/, models/vae/, models/clip_vision/) and is V135+ only. Everything else this node touches - the solve, geometry, layer stack - is dependency-free Python.
Traps
Size sneaks up on you. An 8K plate with six layers measures around 235 MB as a GLB, and the report warns above 200 MB. That's the embedded PNG plates, not the geometry - so if you're emailing the file, raise max_glb_mb and expect a wait, or reduce layers.
The second trap is pathing. Save 3D (Advanced) copies only the GLB into output/3d, so your EXR sidecars stay in the geo/ lane (or wherever the prefix put them). Without a project wired, each reference records exr_output_path relative to ComfyUI's output folder precisely so you can find them afterwards. Wire an AtlasProject and everything lands together, which is the version you want when you're handing the scene to someone else.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| solve | ATLAS_SOLVE | β | |
| source_image | IMAGE | Full-res primary plate (paints the primary relief and generated objects). | |
| write_exropt | BOOLEAN | true | Write one float EXR per layer plate beside the GLB (named in each material's extras). GLB itself cannot hold EXR textures. |
| filename_prefixopt | STRING | atlas/scene | β |
| max_glb_mbopt | INT | 10240β16384 | Refuse a GLB larger than this (MB), naming its size, BEFORE any file is written. 0 = no budget. Values past the GLB format's 4 GiB limit are clamped to it. |
| projectopt | ATLAS_PROJECT | Optional delivery project from AtlasProject: writes the GLB + EXR/PLY sidecars + manifest together into the shot's geo/ lane (supersedes filename_prefix's folder). | |
| hdr_plate_pathopt | STRING | Optional HDR plate EXR of the SAME photo (the matrixZone still workflow's ACEScg output, e.g. atlas/hdr_plate_00001.exr): written as the PRIMARY layer's EXR sidecar instead of the linearised display plate. Must match the source image's size. Relative to ComfyUI's output or input folder, or absolute inside them / $ATLAS_PROJECT_ROOT. The GLB's embedded texture stays the display PNG (glTF has no float textures). A TYPED path re-runs when the file changes; a LINKED one only when upstream does. Empty = no HDR plate. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| model_3d | FILE_3D_GLB | β |
| model_3d_info | LOAD3D_MODEL_INFO | β |
| camera_info | LOAD3D_CAMERA | β |
| glb_path | STRING | β |
| report | STRING | β |