Save 3D (Advanced)
The node that finally turns your mesh into a real file
- model_3d
- viewport_state
- model_3d_info
- camera_info
- model_3d
- model_3d_info
- camera_info
- width
- height
ComfyUI got serious about 3D, and this is the node that gets the result off your canvas and into a file you can actually use - a GLB for your game engine, an STL for the printer, a USDZ for whatever Apple thing you're doing. Save 3D (Advanced) is the mesh-saving half of the new "Save 3D (Advanced)" node family that landed in core around July 2026. Like its siblings it's flagged experimental, which in ComfyUI-speak means "the plumbing works but may shift" - don't build a permanent pipeline around it, but don't avoid it either.
What it does
It's an output node, so it sits at the end of a graph. You feed it a model_3d file object, it writes that file into your output folder, and it shows the result in the 3D viewport with the camera and model metadata attached. Then it passes everything through its outputs so you can chain another save or preview after it if you're exporting multiple copies. That's the whole job, and it's honestly a good job - the old way of exporting 3D from ComfyUI involved custom nodes and guesswork about what format the file would actually be.
How it works
The save itself is simple: the node takes your model_3d, gets the standard output path from ComfyUI's image-save machinery, and writes the file with a counter-suffixed name. Two details matter here. First, the extension comes from the model's own format, not from your filename - a GLTF in stays a GLTF out, an STL stays an STL. Second, the default filename_prefix of 3d/ComfyUI means your files land in output/3d/ as something like ComfyUI_00001_.glb. The counter only bumps when you save with the same prefix again.
The "advanced" part is the viewport wiring. viewport_state is required and comes from a Load 3D or Load 3D (Advanced) node - it's a bundle that carries the camera and model metadata for the 3D viewport. The optional camera_info and model_3d_info inputs override what's inside that bundle when you wire them; leave them empty and the node silently falls back to the viewport state. width and height (1–4096, default 1024) set the preview render size in the viewport. They don't resample your mesh, which trips up more people than it should - your geometry is untouched, this is just how big the preview draws it.
The inputs that actually matter
model_3d- a 3D file object: GLB, GLTF, FBX, OBJ, STL, or USDZ. This is what gets saved.filename_prefix- where and what it's named.3d/ComfyUI→output/3d/ComfyUI_00001_.glb.viewport_state- required, from a Load 3D node. Don't skip the Load 3D; this node leans on it for the camera and metadata.
The trap nobody warns you about
Save 3D (Advanced) eats serialized files, not raw meshes. If your graph produces a MESH tensor - say from Voxel to Mesh after a Hunyuan3D pass - this node won't take it. That's what the older Save 3D Model (SaveGLB) node is for: it saves a mesh tensor directly and needs no viewport plumbing. Think of SaveGLB as the quick export and Save 3D (Advanced) as the proper terminal node for the Load3D-era pipeline. Both ship with core; you just want the right one at the end of your graph.
It's also worth a second to find the file afterward - beginners check input/ or the desktop, but it's always output/3d/ relative to your ComfyUI install.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| model_3d | FILE_3D_GLB,FILE_3D_GLTF,FILE_3D_FBX,FILE_3D_OBJ,FILE_3D_STL,FILE_3D_USDZ,FILE_3D | 3D model file from an upstream 3D node. | |
| filename_prefix | STRING | 3d/ComfyUI | — |
| viewport_state | LOAD_3D | — | |
| width | INT | 10241–4096 | — |
| height | INT | 10241–4096 | — |
| model_3d_infoopt | LOAD3D_MODEL_INFO | — | |
| camera_infoopt | LOAD3D_CAMERA | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| model_3d | FILE_3D | — |
| model_3d_info | LOAD3D_MODEL_INFO | — |
| camera_info | LOAD3D_CAMERA | — |
| width | INT | — |
| height | INT | — |