SphereSplatSeed
Turning a 360° panorama into a splat world you can walk into
- image
- depth
- splats
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: SphereSplatSeed → SplatTrajectoryEnricher (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_fractoo 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.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Equirectangular panorama [1,H,W,3]. | |
| horizontal_fov | FLOAT | 360.001–360 | — |
| radius | FLOAT | 5.000.01–10000 | Sphere radius used when no depth map is provided. |
| splat_scale_frac | FLOAT | 1.500.1–10 | Splat sigma as a fraction of the local point spacing (larger = smoother, fewer holes). |
| stride | INT | 21–64 | Pixel subsampling stride (1 Gaussian per stride x stride block). |
| depthopt | TENSOR | Optional ray-depth map [H,W] (or [1,H,W]/[H,W,1]) matching the panorama. | |
| opacity_logitopt | FLOAT | 6.00-10–20 | — |
| deviceopt | COMBO | auto | 3 options: auto, cpu, cuda |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| splats | GSPLAT | — |