Nodes/ComfyUi-MpiNodes/Mpi Wrap Pad
ComfyUI Node

Mpi Wrap Pad

Hand your upscaler the other side of the 360 seam

By MadPonyInteractive·Created about a year ago·Updated a day ago· 4
Mpi Wrap Pad
  • image
  • IMAGE
◄pad32►

A 360 pano's left edge and right edge are the same place in the world. Inside the image, that's not true: every other column has neighbours, and the wrap column has an image boundary. So a refiner or upscaler working on the pano sees a hard edge where the world continues, and leaves a line there. The pack's own bench note is blunt about it: unpadded, AnimeSharp left a hairline at 8K.

MpiWrapPad is the fix, and it's about as simple as a fix gets. You pad the pano with its own opposite edges, so the wrap looks like any other ordinary column, then run your upscaler or refiner, then cut the pad back off with MpiWrapCrop or MpiWrapCutMerge.

How it works

It copies columns. The last pad columns of the image are put on the left, the first pad columns are put on the right, and nothing else happens. No mirroring, no edge replication - the correct content, because the opposite edge genuinely is the continuation.

That's the whole idea: give the model real context on both sides of the join and it stops treating the join as a border.

Inputs and outputs

  • image - the pano.
  • pad - how many columns are copied onto each side, default 32, range 0–2048.

One output: IMAGE, now width + 2×pad wide.

How wide should pad be? It has to be at least as deep as whatever your next node reaches across the join - a convolution's kernel, a tile's overlap, a refiner's receptive radius. 32 is a reasonable hairline fix for a light upscale pass. For a heavy sharpen pass at high resolution, the pack's own defaults elsewhere go much wider (the cut-merge node's default is 128), and that's a decent hint about what a real 8K pass needed.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/MadPonyInteractive/ComfyUi-MpiNodes
# restart ComfyUI

No models, no weights. This is numpy/torch arithmetic on an image tensor; the whole 360 wrap family (MpiWrapPad, MpiWrapCrop, MpiWrapSoften, MpiWrapCutMerge) is in the pack's MpiNodes/Scene category and nothing outside them is needed. Note that the wrap-soften and cut-merge nodes use scipy, and the pack has no requirements.txt - it depends on what ComfyUI already ships, and those imports are at module level, so a missing dependency takes the whole pack down rather than one node.

The graph shape

MpiWrapPad (pad 128) → upscale / refine → MpiWrapCutMerge (reference = pre-pad image, pad 128)

Which undo node you pick depends on what happened in the middle. If the padding did its job and a plain crop is enough - the two edges still agree - MpiWrapCrop is exact and cheap. If the refiner rendered the right-pad strip and the in-place left columns slightly differently, they now disagree, and a plain crop will show the join. That's what MpiWrapCutMerge is for; it joins the two renders with a hidden cut rather than a fade, so you don't get the doubled ghost line a cross-fade produces.

Where people get burned

Your image is no longer 2:1. Anything downstream that assumes the pano's aspect is now wrong, silently. The pad is exactly what the crop nodes exist to remove - don't leave it on and save.

pad has no idea the image is a pano. Feed it a normal photo and you get duplicate strips stuck on the sides. There's no validation, because there isn't much to validate.

Keep the pre-pad image around. Both undo nodes need it as reference - the crop maths scales the pad by comparing widths, so the reference is how it knows how much to cut after an upscale. If you built the graph without stashing it, that's a rewire, not a setting.

CategoryMpiNodes/Scene

Inputs (2)

NameTypeDefaultDescription
imageIMAGE—
padINT320–2048Columns copied from the opposite edge onto each side.

Outputs (1)

NameTypeDescription
IMAGEIMAGE—