ComfyUI Node

GaussianViewer

Peek inside a gaussian splat and pull a clean frame out of it

By CarlMarkswx·Created 7 months ago·Updated 2 months ago· 108
GaussianViewer
  • extrinsics
  • intrinsics
  • image
  • image
  • extrinsics
  • intrinsics
ply_path

Gaussian splats are the odd middle child of the image-to-3D boom. TRELLIS, Hunyuan3D, and the world-model crowd will all happily hand you a .ply file of millions of colored blobs - and then you can't really look at it. ComfyUI has a bare PreviewGaussianSplat that shows the thing, but nothing that lets you aim a camera and pull a production-quality frame. GaussianViewer is that missing piece: an interactive 3D viewer embedded right in the graph, with a renderer bolted on, in a single node.

The flow is: drop in a splat, orbit it with your mouse, click Set Camera, and out comes an IMAGE at a 2048px short edge that flows into the rest of your workflow like any other image. Upscale it, inpaint it, feed it to Qwen-Image-Edit to fill in what's behind the camera - that last one is honestly the workflow where this node shines. The "Gaussian Splash" 3D-camera-motion demos making the rounds in early 2026 were basically splat → GaussianViewer → new angle → image-edit cleanup. It's the cheapest way to "move the camera" on a still image that exists right now.

How it works (worth knowing, because it decides where problems come from)

The node is a fork of ComfyUI-GeometryPack's viewer, and the actual rendering happens in your browser, not your GPU. Python validates the file and ships the PLY path to an embedded iframe running gsplat.js (the same open-source WebGL renderer behind a lot of splat viewers). The JavaScript fetches the file through ComfyUI's /view endpoint, renders it with WebGL, and when you hit Set Camera it draws the current view to a canvas, base64-encodes it, and POSTs it back to a /geompack/render_result endpoint. Python converts that to a torch tensor and hands it to the graph. The 30-second render timeout and the gray placeholder you sometimes get are both consequences of this browser round-trip, so keep that architecture in your head.

The inputs and outputs that matter

  • ply_path (required) - path to the splat. It's forceInput, so you can wire it from a path node rather than typing it.
  • extrinsics (optional) - a 4x4 camera-to-world matrix that sets the initial view.
  • intrinsics (optional) - a 3x3 matrix that sets focal length / FOV.
  • image (optional) - a reference image shown as an overlay, handy for aligning your splat against the source photo.

Outputs: image (IMAGE), plus extrinsics and intrinsics for whatever camera you ended up at - useful if you want to reproduce that exact view later, or feed them into the pack's ExtrinsicsToPose to read the numbers.

Using the viewer

Left-drag to orbit, right-drag to pan, wheel to zoom; WASD/QE/RF/ZC and Shift for finer movement. The bottom bar is grouped into View / Camera / Display / Presets. Two things actually matter: the Image Ratio selector in the corner sets the output crop, and - the big one - you must click Set Camera before queueing a render, or you render whatever cached camera state was last saved. Camera state is cached per PLY, so it survives re-runs.

Install

ComfyUI Manager, search "GaussianViewer", or:

cd ComfyUI/custom_nodes
git clone https://github.com/CarlMarkswx/comfyui-GaussianViewer.git

then restart. Dependencies are just numpy / torch / Pillow - already part of ComfyUI. No model downloads, no CUDA compiles. That's the whole appeal versus ComfyUI-3D-Pack, the usual heavyweight for gaussian tooling, which is famously a build-your-own-CUDA-extensions nightmare.

Troubleshooting

  • PLY won't load / "file not found" - the file needs to live inside ComfyUI's output folder (or somewhere /view can serve it). The README calls this out explicitly.
  • Render times out, blank placeholder - either you're rendering a giant splat in the browser and blew past the 30s cap, or you queued the workflow without the browser tab open. Shrink the splat, close other tabs, or raise the timeout in render_gaussian.py.
  • Blank image with a valid file - README's advice: check whether the PLY is actually valid, and try running without extrinsics so it uses the default view.
  • Node renders squished/narrow under the new Nodes 2.0 frontend - a known family of issues; the README's checklist is update the plugin, hard-refresh the browser, disable "Auto scale layout (Nodes 2.0)" in settings, or pin an older frontend:
python main.py --front-end-version Comfy-Org/[email protected]

Last one is worth knowing: the plugin prints your frontend version to the console at startup, so when a workflow suddenly looks broken after a ComfyUI update, that line tells you what changed.

Categorygeompack/visualization

Inputs (4)

NameTypeDefaultDescription
ply_pathSTRINGPath to a Gaussian Splatting PLY file
extrinsicsoptEXTRINSICS4x4 camera extrinsics matrix for initial view
intrinsicsoptINTRINSICS3x3 camera intrinsics matrix for FOV
imageoptIMAGEReference image to show as overlay

Outputs (3)

NameTypeDescription
imageIMAGE
extrinsicsEXTRINSICS
intrinsicsINTRINSICS