Pano Sweep (Seb)
Pano Sweep (Seb) hands you a tile list for the whole sphere — 25 views at the defaults
- yaw
- pitch
- total
- wrapped_index
- info
Everyone tries to generate directly in equirectangular first, and everyone hits the same wall: the 2:1 projection stretches things badly toward the poles, and the resolution people usually generate panoramas at doesn't leave much detail per degree of sphere. The alternative is the one Seb built these nodes around - cut the sphere into overlapping rectilinear windows, generate each one at full resolution where the model behaves like it's working on a normal photo, then blend the results back onto the sphere.
Pano Sweep is the boring-but-essential first step of that: it turns a running index into a yaw/pitch pair. It draws no pixels and reads no panorama. It's a grid, and a well-thought-out one.
How the grid is laid out
The math is in _sweep_positions, and the shape of it is the interesting part. Step size between tiles is core_fov × (1 − overlap_pct/100), floored at 1°. Rows are spaced step apart from −90 to +90 in pitch, with the exact poles dropped. So far, so obvious.
The non-obvious bit is the columns. A fixed grid would put the same number of tiles in every row, which means the rows near the poles - where a circle of latitude is physically tiny - get packed with tiles that all look at nearly the same patch of sky, while the equator is starved. So columns per row are scaled by cos(pitch): ceil(360 × cos(pitch) / step), with that cosine floored at 0.15 so the top and bottom rows don't explode into hundreds of near-duplicate tiles.
At the defaults - core_fov 53.5, overlap_pct 15 - that works out to step 45.5°, four pitch rows holding 4, 8, 8 and 3 tiles, plus the two pole tiles include_poles appends: 25 tiles total. Push overlap to 30% and it's 34. Go to 50% for a difficult scene and it's 65. Drop overlap to 0 and it's 18, with visible gaps. That table is worth internalising, because it's also your queue length.
Then the node does nothing clever: pos[index % total], and out come yaw and pitch. The modulo is deliberate - over-queue and the sweep wraps around and starts again instead of erroring.
Driving it
Set index, then set the integer widget's control_after_generate to increment, then queue runs. Each execution advances one tile. If you've never touched that dropdown: it fires after the run by default, which is how people lose a seed, and the global fix is the app setting that flips widget control to "Before" - worth doing once regardless. Wire yaw and pitch into Read 360 by converting those widgets to inputs.
core_fov should be the framing FOV you extract at - 53.5 is a normal-ish lens and the default for a reason. overlap_pct is how much neighbouring tiles share; Read 360's margin_deg is the extraction ring it uses for blending context, so the two settings are solving one problem from either end. Keep the overlap generous enough that Write 360 has something to feather into.
Then it's the loop this whole pack exists for: Read 360 → generate → Write 360. In commit mode you can leave it running unattended across all 25 tiles; in stage mode you approve each one from the node panel before it lands. total tells you how many runs to queue, wrapped_index tells you where you are, and info prints a readable line to the console.
The outputs
yaw, pitch (FLOAT) are the camera. total (INT) is the tile count for the current settings - use it as your queue count or loop bound. wrapped_index is the index after the modulo. info is the human-readable summary: tile 7/25 | yaw -157.5 pitch 23.7 | core 53.5 overlap 15%.
Installing it
Part of Seb Nodes - Manager, search seb_nodes, install, restart completely. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/cyberhirsch/seb_nodes
No models. The pack pip-installs its Python deps (OpenCV among them) on first import, so expect a pause on the first start after install.
Where it bites
Changing settings mid-sweep throws your grid away. The node is stateless - core_fov and overlap_pct are inputs, not saved state, and they're recomputed every run. If you're at tile 12 of 25 and you nudge the FOV, tile 13 is now somewhere else entirely and the tiles you already committed no longer line up with the ones coming. Finish the sweep on the settings you started with, then re-do it properly if you need different framing.
It doesn't know anything about your panorama. This is a uniform grid over a sphere. If there's one thing in the scene that has to be shot dead-on - a doorway, a sign - set that yaw/pitch by hand on a separate Read 360 and let the sweep do the filler.
It re-runs every time. IS_CHANGED returns NaN so ComfyUI won't cache it; that's required for an index-driven node, and it costs you nothing measurable here.
The two pole tiles are usually worth keeping. They're cheap, they stop a hole at the zenith and nadir, and include_poles is one tick to switch off if your source genuinely ends at flat sky and floor.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| index | INT | 00–4096 | — |
| core_fov | FLOAT | 53.55–170 | — |
| overlap_pct | FLOAT | 150–60 | — |
| include_poles | BOOLEAN | true | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| yaw | FLOAT | — |
| pitch | FLOAT | — |
| total | INT | — |
| wrapped_index | INT | — |
| info | STRING | — |