Nodes/ComfyUI-DirectorTools/Super Director Tools · Panorama Shift
ComfyUI Node

Super Director Tools · Panorama Shift

The Seam Is at the Edge of the Image, Where You Can't See It

By mch000534·Created 7 days ago·Updated 5 days ago· 0
Super Director Tools · Panorama Shift
  • image
  • image
  • prompt
◄shift_x0.500►

An equirectangular panorama is a sphere unwrapped into a 2:1 rectangle. Which means it has a join: the pixel column at the far left is supposed to continue into the column at the far right, and the model that made it never once looked at those two columns side by side.

You can't inspect a seam sitting on the edge of your image - two panes, one at each side of the window, no way to compare them. That's the entire reason this node exists: roll the panorama and the join lands in the middle of the frame, where you can see it and where an inpainting pass can reach it.

What it does

shift_x is a fraction of image width, from -1 to 1, defaulting to 0.5. Positive shifts right, negative left. At 0.5 the original left/right join moves to the centre, and everything that fell off one side reappears on the other.

It's a torch.roll - a circular shift. No cropping, no padding, no resampling, no interpolation. Every pixel is the same pixel it was, just at a different column, and the image keeps its size, dtype and device. It takes 1-, 3- or 4-channel images and whole batches. Shifts are rounded to whole pixels, halves away from zero, so an odd-width panorama puts the join a hair off exact centre. And 0, 1 and -1 are no-ops by design - a full width of shift returns the original.

The prompt output, which is the interesting half

The node has two outputs: image and prompt. The image is the rolled panorama. The prompt is an English img2img instruction that tells your downstream model exactly where the seam now is - for a 2048-wide panorama, "the vertical boundary at x=1024 pixels from the left (50.00% of image width), between columns 1023 and 1024 using zero-based pixel coordinates" - plus a very emphatic set of constraints: lock the left and right regions including both outer edge columns, do not relight, recolour, sharpen or blend them, and repaint only the minimum interior strip needed.

That "lock the outer edges" instruction is doing real work. After a 0.5 shift, the outer edges are the good part of the wraparound - the part that already matched before you started. If your model redraws those, it breaks the one thing you were fixing. The prompt also handles the degenerate case: shift by 0 and it tells the model to return the image unchanged and to go use 0.5 first, rather than pretending there's something to repair.

prompt goes into whatever your img2img pipeline reads text from - a CLIP Text Encode text input. Convert the widget to an input if it won't accept a link.

The workflow

Load Image → Panorama Shift (0.5) → Preview Image      # inspect the join
Load Image → Panorama Shift (0.5) → img2img (prompt, low denoise) → Panorama Shift (-0.5) → Save

The second node undoes the roll: 0.5 → -0.5 puts you back, as long as the model preserved dimensions.

One honest caveat the README is upfront about: text can't force a diffusion model to leave pixels alone. If you need the outer regions bit-identical, mask the repair - a narrow vertical strip over the centre - and composite the result back over the shifted original. That's the case for masked inpainting over instruction editing in general: instruction models regenerate the whole frame and come back close rather than identical, and near-identical edges are what breaks a wraparound. Use the prompt with a mask, not instead of one.

Reality check on panoramas

Equirect generation is still a niche with sharp edges: models stretch at the poles, they sometimes decide to give you a perspective crop or a little-planet view instead of a proper panorama, and the wrap seam is where the failure concentrates. Some pipelines attack that geometrically - cubemap reprojection, pole inpainting - rather than fussing with the equirect join directly. A shift-and-inpaint pass is the cheap version of that idea, and it's a good first move when the sky and ground are fine and only the sideways join is visibly wrong.

It won't fix a panorama that was never equirect in the first place. If you roll 50% and the "seam" is a completely different horizon line, no amount of local repaint is saving it - regenerate.

Install

Manager → search Super Director Tools, or:

cd ComfyUI/custom_nodes
git clone https://github.com/mch000534/ComfyUI-DirectorTools

Restart and refresh. No dependencies beyond the torch/numpy/Pillow ComfyUI already ships, and nothing to download - the work happens in a downstream img2img model you supply. The pack is MIT.

The traps

Batches are fine here, but Batch Panorama is not - it wants one panorama. A one-pixel-wide image has no interior seam and the node says so rather than guessing. And if shift_x errors, check you didn't feed it a bool or something outside -1..1; the validation is strict and throws shift_x must be finite and between -1 and 1.

Categoryimage/Super Director Tools

Inputs (2)

NameTypeDefaultDescription
imageIMAGEEquirectangular panorama, usually 2:1. Supports IMAGE batches.
shift_xFLOAT0.500-1–1Fraction of image width. Positive moves right, negative left. 0.5 moves the original left/right join to the middle. Circular, rounded to whole pixels.

Outputs (2)

NameTypeDescription
imageIMAGE—
promptSTRING—