Nodes/camera-comfyUI/SphereSplatSeed
ComfyUI Node

SphereSplatSeed

Turning a 360° panorama into a splat world you can walk into

By Alexankharin·Created about a year ago·Updated about a month ago· 36
SphereSplatSeed
  • image
  • depth
  • splats
horizontal_fov360.00
radius5.00
splat_scale_frac1.50
stride2
opacity_logit6.00
deviceauto

An equirectangular panorama is a flat 2:1 image that contains a full 360° world - but it's not a 3D world you can move around in. SphereSplatSeed converts the panorama into a sphere of Gaussian splats: one Gaussian per (subsampled) pixel, placed in 3D around the origin, so the image becomes an actual 3DGS scene you can render from any angle. It's the "turn a 360° panorama into a splat world" node, and it's the starting point for the pack's world-building workflows.

Here's the honest caveat up front: without a depth map, the splats get placed on a sphere of fixed radius (default 5), which is fake geometry - everything at arm's length. It looks fine for small camera moves, but translate sideways and you'll feel the flatness. Feed it a real depth tensor and the Gaussians get placed at actual distances, which is the difference between a panorama you can spin and a world you can walk. Depth can come from any of the pack's depth nodes (a 360° depth map from DepthEstimatorNode on the equirect, or VGGT's estimate for a video panorama).

How it works

It unprojects the equirectangular pixel grid to longitude/latitude rays, multiplies by the ray depth (or the fixed radius), and places a Gaussian at each (subsampled) 3D point, taking its color from the image. Each splat's size - splat_scale_frac (default 1.5) times the local angular point spacing, times depth - is set so neighboring Gaussians overlap and the sphere renders without holes. stride (default 2) controls how many pixels each Gaussian represents: 1 = every pixel (dense, slow), 2+ = subsampled (fast, coarser). opacity_logit (default 6) sets opacity in logit space; raise it if the world looks translucent.

The inputs

  • image - [1,H,W,3] equirectangular panorama.
  • horizontal_fov - 360 by default (full panorama); lower if your "panorama" only covers part of the sphere.
  • radius - sphere radius used when no depth is given.
  • splat_scale_frac, stride, opacity_logit - the appearance/coverage knobs above.
  • depth - optional ray-depth map [H,W] (or [1,H,W]/[H,W,1]), resampled to match the image.
  • device - auto/cpu/cuda.

Output: a single splats GSPLAT.

Where it fits

In the world-building story: SphereSplatSeedSplatTrajectoryEnricher (outpaint and lift along a walk path) → SplatPolish → render. A panorama becomes a seed world, which becomes a walkable world. For VR content, that's the difference between a static 360 image and an environment with parallax.

Installing it

Part of camera-comfyUI. Manager → Custom Nodes Manager → camera-comfyUI → Install → restart, or:

cd ComfyUI/custom_nodes
git clone https://github.com/Alexankharin/camera-comfyUI.git
cd camera-comfyUI && python install.py

Seeding needs no optional deps; rendering and enriching the result benefit from gsplat and SHARP.

Common issues

  • Holes in the sphere - splat_scale_frac too small for the stride you chose. Raise it, or lower the stride.
  • Flat, "cardboard" look when moving sideways - no depth input; the sphere is constant-radius. Add a real depth map.
  • Translucent world - opacity too low; raise opacity_logit.
  • Slow with big panoramas - lower the stride. Each splat is a render cost.
CategoryCamera/World

Inputs (8)

NameTypeDefaultDescription
imageIMAGEEquirectangular panorama [1,H,W,3].
horizontal_fovFLOAT360.001–360
radiusFLOAT5.000.01–10000Sphere radius used when no depth map is provided.
splat_scale_fracFLOAT1.500.1–10Splat sigma as a fraction of the local point spacing (larger = smoother, fewer holes).
strideINT21–64Pixel subsampling stride (1 Gaussian per stride x stride block).
depthoptTENSOROptional ray-depth map [H,W] (or [1,H,W]/[H,W,1]) matching the panorama.
opacity_logitoptFLOAT6.00-10–20
deviceoptCOMBOauto3 options: auto, cpu, cuda

Outputs (1)

NameTypeDescription
splatsGSPLAT