Nodes/ComfyUI-ArchAi3d-Qwen/πŸ’Ύ Save Splat Scene (SPZ + Camera)
ComfyUI Node

πŸ’Ύ Save Splat Scene (SPZ + Camera)

Turn your 3D Gaussian splat PLY into a web-ready SPZ with a camera sidecar

By amir84ferdosΒ·Created 11 months agoΒ·Updated 5 months agoΒ· 70
πŸ’Ύ Save Splat Scene (SPZ + Camera)
  • extrinsics
  • intrinsics
  • include_source_image
  • spz_path
  • json_path
  • scene_info
β—„ply_pathβ€”β–Ί
β—„output_namesceneβ–Ί
β—„image_width1024β–Ί
β—„image_height768β–Ί
β—„output_formatspzβ–Ί
β—„coordinate_systemRDFβ–Ί

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 spz needs 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_system against 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.

CategoryArchAi3d/3D/Export

Inputs (9)

NameTypeDefaultDescription
ply_pathSTRINGPath to input PLY file from SharpPredict or similar
output_nameSTRINGsceneBase name for output files (scene.spz, scene_camera.json)
extrinsicsoptEXTRINSICSCamera extrinsics (position/rotation) from SHARP
intrinsicsoptINTRINSICSCamera intrinsics (focal length, FOV) from SHARP
image_widthoptINT10241–8192Original image width for FOV calculation
image_heightoptINT7681–8192Original image height for FOV calculation
output_formatoptCOMBOspzOutput format: spz (compressed), ply_copy, or both
coordinate_systemoptCOMBORDFInput PLY coordinate system (RDF=PLY default, RUB=OpenGL/Three.js)
include_source_imageoptIMAGEOptional: include source image path in JSON

Outputs (3)

NameTypeDescription
spz_pathSTRINGβ€”
json_pathSTRINGβ€”
scene_infoSTRINGβ€”