πΎ Save Splat Scene (SPZ + Camera)
Turn your 3D Gaussian splat PLY into a web-ready SPZ with a camera sidecar
- extrinsics
- intrinsics
- include_source_image
- spz_path
- json_path
- scene_info
Most of the ArchAi3d Qwen pack is about prompts. ArchAi3D_SaveSplatScene - "πΎ Save Splat Scene (SPZ + Camera)" - is the odd one out: it's an export node for 3D Gaussian splats, and it's the piece that turns a render into something a web viewer can actually load. Feed it a PLY file, and it writes a compressed .spz plus a _camera.json sidecar into ComfyUI's output folder, so a 3D scene shows up in a browser app with the camera already placed.
The ply_path input is the star: it's meant to come from "SharpPredict or similar" - i.e., a 3D Gaussian splat generator like Sharp (the two-view splat predictor that went viral for turning a couple of photos into a navigable scene). That's the intended pipeline: predict the splat β SaveSplatScene β open the SPZ + camera JSON in a web viewer. The optional extrinsics and intrinsics inputs (types EXTRINSICS/INTRINSICS, "from SHARP") are how the camera pose gets captured at export time instead of being guessed later.
How it works
The mechanism is a three-tier PLYβSPZ conversion. It tries the Niantic spz library first (C++ - the pack's install.py goes so far as to attempt installing zlib1g-dev for it), falls back to gsconverter (Python, slower but always works), and finally to a built-in SPZ v3 converter in the node itself. output_format lets you pick spz, ply_copy, or both. The coordinate_system input (RDF default, plus RUB/LUF/RUF) tells the converter what handedness your PLY is in - RDF is the standard 3DGS output, RUB is OpenGL/Three.js - so the camera math lines up. image_width/image_height feed the FOV calculation from the intrinsics.
Outputs: spz_path, json_path, and a scene_info summary string - everything a downstream app needs to know where the files landed.
Installing it
It's part of ComfyUI-ArchAi3d-Qwen (author: Amir Ferdos / ArchAi3d), and it's the one node whose install actually does work:
# ComfyUI Manager: search "ArchAi3d Qwen"
cd ComfyUI/custom_nodes
git clone https://github.com/amir84ferdos/ComfyUI-ArchAi3d-Qwen.git
cd ComfyUI-ArchAi3d-Qwen
pip install -r requirements.txt
Restart. ComfyUI Manager runs the pack's install.py on install, which tries to set up the SPZ toolchain - that's where the C++ compiler and zlib requirements come in. The good news: the node's built-in converter means you're never hard-blocked if the native libs fail to compile, just slower.
Common issues
- The SPZ toolchain is the flaky part. Niantic's
spzneeds a C++ compiler and zlib dev headers; on Windows or a locked-down container the pip install from the git URL can fail. You still get output via the fallback converters - expect 30β100s instead of 1β5s. - Coordinate system mismatches make the camera point wrong. If your viewer shows the scene sideways or the camera inside a wall, check
coordinate_systemagainst how your splat was generated - RDF vs RUB is the classic offender. - It expects a PLY that already exists. This node doesn't generate splats; it converts them. SharpPredict (or any 3DGS PLY exporter) must run first.
- Web-viewer expectations vary. Some viewers want specific SPZ versions or their own camera format; the JSON sidecar is a custom convenience, so check your target app's docs.
If you're already producing splats in ComfyUI and want browser-friendly output, this is the missing export step - the built-in fallback converter is what keeps it honest when the fancy C++ path breaks.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| ply_path | STRING | Path to input PLY file from SharpPredict or similar | |
| output_name | STRING | scene | Base name for output files (scene.spz, scene_camera.json) |
| extrinsicsopt | EXTRINSICS | Camera extrinsics (position/rotation) from SHARP | |
| intrinsicsopt | INTRINSICS | Camera intrinsics (focal length, FOV) from SHARP | |
| image_widthopt | INT | 10241β8192 | Original image width for FOV calculation |
| image_heightopt | INT | 7681β8192 | Original image height for FOV calculation |
| output_formatopt | COMBO | spz | Output format: spz (compressed), ply_copy, or both |
| coordinate_systemopt | COMBO | RDF | Input PLY coordinate system (RDF=PLY default, RUB=OpenGL/Three.js) |
| include_source_imageopt | IMAGE | Optional: include source image path in JSON |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| spz_path | STRING | β |
| json_path | STRING | β |
| scene_info | STRING | β |