Write 360 (Seb)
Write 360 (Seb) puts the generated view back on the sphere — and lets you approve it first
- pano_ref
- image
- view_info
- mask
- pano_ref
This is the second half of Seb's 360 loop, and it's the half that decides whether the result looks like a panorama or like a mosaic of pasted rectangles. Read 360 pulls a flat, properly-projected window out of the sphere; you generate in that window where the model is happy; Write 360 back-projects the result onto the sphere and blends it in.
Getting the blend right is the problem. Pasting a hard-edged rectangle into an equirect produces a visible seam, and worse, the model's output is at its least reliable right at the edges of what it saw. Write 360's answer is to make the boundary land somewhere you can afford to throw away.
How the blend works
Take the generated image, and build an alpha for it. If you wired a mask, that's your alpha - and the node feathers its outer edge by the same ring the falloff uses, so even Read 360's hard core mask can't stop the write dead at its boundary. No mask, and the whole frame gets a flat alpha of blend_strength.
Then it multiplies by the core falloff: a smoothstep ramp that's fully opaque across the framed core and fades through the margin ring you paid for in Read 360's margin_deg. Only then is the patch back-projected into equirect space at the store's resolution and composited over the committed layer with a normal source-over alpha.
The upshot: the part of the generation you trust lands at full strength, the unreliable edge fades out inside a ring Read 360 extracted as disposable context, and the next tile's feather falls in the same overlap. That's why the sweep's overlap_pct and the read node's margin_deg are the same decision made from two ends.
feather controls how much of that margin ring is used as the blend ramp. At 0 you get a hard edge at the framed FOV; at 1 the fade runs all the way to the extracted edge. 0.6 is a sensible starting point - enough ramp to hide the transition, not so much that a legitimately new detail gets faded into nothing.
stage vs commit, which is the whole personality of this node
In stage mode the warped candidate goes into a pending list rather than onto the sphere. The node face then shows staged 1 of N, a candidate number, a follow-candidate toggle, and three buttons: Commit Candidate, Discard Staged, Export to Disk. So the workflow is generate, look, decide, move on. Eight candidates are held; past that the oldest drop.
In commit mode it merges immediately, no review - what you want for an unattended pass over 25 tiles from Pano Sweep.
update_reference decides whether the committed layer gets folded back into the base the preview and next extraction read from. Leave it on unless you deliberately want the committed work kept separate; it's captured at the moment the node stages, so a later commit honours the flag you set when staging.
Inputs and outputs
pano_ref, image and view_info all come from Read 360 - the two handle types exist precisely so the sphere and the camera survive the trip through your sampler. blend_strength (0–1) is the overall opacity of the write. mode, update_reference and feather are as above, and mask is the optional per-pixel control.
One output: pano_ref, the same handle coming back out. Wire it into the next Read 360 and successive tiles accumulate into the same sphere as long as the source filename matches. That's the loop - read, generate, write, next tile, with the sphere persisting between runs.
Installing it
Part of Seb Nodes. Manager → search seb_nodes → install → restart ComfyUI fully, or:
cd ComfyUI/custom_nodes
git clone https://github.com/cyberhirsch/seb_nodes
No models to download. The pack installs its own Python deps (OpenCV, numpy, PIL) on first import via a startup check, so the first launch after install prints a few pip lines.
Where people get burned
The node runs and writes nothing. If the pano_ref isn't in the store - fresh ComfyUI session, an evicted panorama, or a fifth panorama loaded - Write 360 quietly returns the id and does nothing. No error, no red node. Read the console: it prints Committed N view(s) or Staged N candidate(s) on success, and silence is the tell.
"I committed and lost it." The store is memory only, and committing is not saving. Export to Disk is the save - a 16-bit PNG into ComfyUI's output folder named Seb_360_Export_<timestamp>.png, reporting a peak value so you know how much clipped. 16-bit rather than 8 because the store is float and a feathered multi-tile sweep accumulates more range than one byte holds; above-range values survive in the store and clip on export.
Nothing appears to change after a commit. Write 360 is an output node, so it always runs and the cache works backward from it - that part is fine. But if update_reference is off, the composited layer isn't fed back into the base the preview reads, and Read 360's next extraction still starts from the un-edited pixels.
Changing canvas_width mid-project. It resamples the committed layer rather than dropping it, which is friendly, but you're still resampling a finished result - decide the working resolution before you start sweeping and leave it alone.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| pano_ref | PANO_REF | — | |
| image | IMAGE | — | |
| view_info | PANO_VIEW_INFO | — | |
| blend_strength | FLOAT | 1.000–1 | — |
| mode | COMBO | 2 options: stage, commit | |
| update_reference | BOOLEAN | true | — |
| feather | FLOAT | 0.600–1 | How much of the margin ring is used as a blend ramp. 0 = hard edge at the framed FOV, 1 = fade all the way to the extracted edge. |
| maskopt | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| pano_ref | PANO_REF | — |