Nodes/InfiniSplat - 3D Gaussian Splatting/InfiniSplat (Image to PLY)
ComfyUI Node

InfiniSplat (Image to PLY)

One photo in, an orbitable splat out

By jKaarlehto·Created 24 days ago·Updated 24 days ago· 3
InfiniSplat (Image to PLY)
  • image
  • intrinsics
  • model_3d
  • file_path
◄focal_length_mm30.0►
◄gaussian_count1500000►
◄query_chunk_size20000►
◄seed0►
◄filter_floaterstrue►
◄download_modeltrue►
◄savefalse►
◄file_pathinfinisplat/InfiniSplat►
◄camera_estimationmanual►

Single-image-to-3D is the corner of the ecosystem where the demo always looks better than the deliverable. Gaussian splats are the friendliest output format it has, precisely because nobody promised you clean topology - you get a cloud of soft blobs that renders beautifully from an angle you never photographed. InfiniSplat (Image to PLY) wraps Zhejiang University's InfiniSplat so one RGB image becomes exactly that, in a graph, with a native viewport.

If you've tried ComfyUI-3D-Pack, you know the real barrier here isn't VRAM, it's compiled-dependency roulette. This pack sidesteps it: upstream runs in its own isolated venv, not in ComfyUI's Python.

How it works

The node stages each input image as a PNG, then launches upstream in a separate worker process using that isolated interpreter rather than ComfyUI's. The model predicts a depth map and image features, samples points on the implied surface, and decodes one gaussian per sample - those queries are chunked, which is what query_chunk_size sizes. A floater filter runs, then the result is written as a .ply and loaded back as a native FILE_3D_PLY. Your cached ComfyUI models get unloaded first, so expect your Flux checkpoint to be evicted; the worker loads once per batch, not once per image.

The inputs that matter

  • focal_length_mm (default 30) - a 35mm-equivalent focal length, and it is not estimated from your image: ComfyUI IMAGE tensors carry no EXIF, so the node builds centered intrinsics from the image size and this number. Wide-angle? Push it down. Telephoto crop? Push it up, or the splat looks squashed from the side.
  • gaussian_count (default 1,500,000, max 4,000,000) - your quality/size dial. query_chunk_size (default 20,000) is the memory one: lower it first if you OOM. Upstream ships 80,000, so the pack is already conservative.
  • filter_floaters (on) prunes stray gaussians and can pull the exported count below gaussian_count. download_model lets the node fetch the checkpoint on first execution.
  • save (off) plus file_path - off means a temp file that only feeds the preview. On means a permanent PLY in output/ (infinisplat/InfiniSplat_00001.ply) plus a .camera.json sidecar.

seed only drives the randomized surface sampling.

Outputs and wiring

model_3d is the one you came for: a list of FILE_3D_PLY, one per input image (square sockets mean list processing). Wire it into ComfyUI's built-in Preview Splat (PreviewGaussianSplat) to orbit the result inside the graph, or into 3D File to Splat for the native tensor path. The second output, file_path, exists only when save is on - disable Save and it vanishes with its links, which is a fun way to break a graph.

Install

ComfyUI Manager, search InfiniSplat, or:

cd ComfyUI/custom_nodes
git clone https://github.com/jKaarlehto/ComfyUI-InfiniSplat

That alone won't run it - the runtime lives in its own venv. From inside the pack folder, with uv installed:

cd ComfyUI/custom_nodes/ComfyUI-InfiniSplat
uv run --no-project install.py          # add --camera for GeoCalib

Then restart ComfyUI and look under 3d/InfiniSplat. The installer builds .venv with torch 2.9 + CUDA 12.8 and requirements-runtime.txt (scipy, opencv-headless, plyfile, timm and friends) inside it, clones upstream at a pinned revision, and patches it. None of it touches ComfyUI's Python environment, and the checkpoint lands in ComfyUI/models/infinisplat/checkpoints/infinisplat_rgb.ckpt (redirectable via extra_model_paths.yaml).

You need ComfyUI 0.39.2+, an NVIDIA CUDA GPU, and Windows or Linux. The author tested Windows on an RTX 5090 Laptop; Linux is supported but untested.

Cameras, if you bother

Manual focal length is the default and is fine for most work. camera_estimation: geocalib instead estimates intrinsics per image (install that with --camera), but only focal and roll/pitch. Or feed normalized matrices into intrinsics from something like MoGe2 - (B,3,3) or (B,4,4), one matrix broadcasting to a batch, which beats both other modes but must match the image size and crop you fed the node.

Where people get burned

  • "InfiniSplat runtime is missing. Run: uv run --no-project install.py." You installed the node but skipped the venv step, or upstream/ never cloned. A Manager install won't do it for you.
  • RuntimeError: This InfiniSplat runtime requires an NVIDIA CUDA GPU. No CPU or ROCm path; macOS, AMD and CPU-only boxes are out. OOM on 12GB? Halve query_chunk_size, then drop gaussian_count.
  • Nothing in the output folder. With save off the PLY is a temp file by design, kept only long enough to feed the preview.
  • A wall of text as the error. The node raises the last 8000 characters of the worker's log - the real traceback. Read it before assuming anything.
  • The depth-guided checkpoint isn't offered. Upstream's xFormers kernels and its fallback both fail on the tested SM120 card.

One licensing note before you ship anything: InfiniSplat is under upstream's Project Registration License - personal and research use free, organizational use requiring registration. The wrapper is MIT; the weights are not.

The field is young enough that "which model" is unsettled (TripoSplat and Apple's SHARP are the other names here), and InfiniSplat has almost no community chatter yet. You reach for it when you want a splat in a graph without the install fight.

Category3d/InfiniSplat

Inputs (11)

NameTypeDefaultDescription
imageIMAGE—
focal_length_mmFLOAT30.00.1–50035mm-equivalent focal length.
gaussian_countINT150000010000–4000000—
query_chunk_sizeINT200001000–160000Lower values reduce peak memory; the upstream default is 80000.
seedINT00–18446744073709550000—
filter_floatersBOOLEANtrue—
download_modelBOOLEANtrueDownload the selected checkpoint on execution if it is missing.
saveBOOLEANfalseSave a permanent PLY in the output directory; otherwise keep a temporary file for preview.
file_pathoptSTRINGinfinisplat/InfiniSplatFilename prefix relative to ComfyUI's output directory. A counter and .ply extension are added.
camera_estimationoptCOMBOmanualGeoCalib estimates intrinsics per image. Requires install.py --camera. Connected intrinsics take precedence.
intrinsicsoptINTRINSICSNormalized camera matrices, shape (B,3,3) or (B,4,4), e.g. MoGe2. One matrix broadcasts to the image batch.

Outputs (2)

NameTypeDescription
model_3dFILE_3D_PLY—
file_pathSTRING—