ComfyUI Node

Equirectangular Rotate

Spin a 360° image in all three axes — the node this pack is built around

By cedarconnor·Created about a year ago·Updated 7 months ago· 2
Equirectangular Rotate
  • image
  • rotated_image
yaw_rotation0.0
pitch_rotation-65.0
roll_rotation0.0
horizon_offset0.0
interpolationlanczos
backendauto
use_tilingauto
tile_size2048

This is the flagship. Every 360° photo you load into ComfyUI is stuck in whatever orientation the camera recorded, and Equirectangular Rotate is how you fix that - and how you point the view anywhere you want. It's the reason the pack exists: rotate with yaw/pitch/roll, nudge the horizon, done.

Concretely: drop in an equirectangular image, adjust yaw_rotation to look left or right around the horizon, pitch_rotation to tilt up or down, roll_rotation to bank the image (useful when the camera was mounted crooked), and horizon_offset to shift the visible horizon line vertically without tilting everything. One node, no external parameter widgets - v2.0 of the pack moved all controls inline.

How it works

The rotation is a proper spherical transform, not a picture rotation. The node builds a rotation matrix from your yaw/pitch/roll using scipy.spatial.transform.Rotation, applies it to the direction vector of every output pixel, converts back to latitude/longitude, and samples the source image - again the inverse-remap approach with OpenCV, wrapping longitude so nothing falls off the edge.

Two backends, and this is the part people trip on:

  • CPU (OpenCV remap) - supports all four filters: lanczos, bicubic, bilinear, nearest. Lanczos is the default and gives the cleanest result.
  • GPU (torch.grid_sample) - faster, but only bilinear and nearest. If you pick lanczos with backend on auto and have a GPU, the node quietly falls back to bilinear on the GPU path. For final renders you often want the CPU lanczos pass; the GPU is for previews and batch work.

There's also tiled processing for the big stuff. Images wider than 8192px (16K panoramas, ~1.6GB in memory) get processed in horizontal bands with a 64px overlap, cutting memory use by 60–75%. use_tiling auto-enables this above 8K; tile_size (default 2048, range 512–8192) trades memory against speed - smaller tiles, less RAM.

Inputs that matter

  • image (required) - equirectangular tensor (B,H,W,C) in [0,1].
  • yaw_rotation / pitch_rotation / roll_rotation - the three axes, in degrees. Note the default pitch_rotation is −65°, not 0. That's a deliberate "tilt the view down toward the horizon band" default; set all three to 0 for a true no-op.
  • horizon_offset - vertical horizon shift in degrees; positive moves the horizon up.
  • interpolation - default lanczos; see above for the GPU caveat.
  • backend - auto | cpu | gpu.
  • use_tiling / tile_size - for 16K+ sources.

Output is a single rotated_image, ready to feed any downstream node.

Installing it

ComfyUI Manager → search "LatLong", or:

cd ComfyUI/custom_nodes
git clone https://github.com/cedarconnor/comfyui-LatLong
cd comfyui-LatLong
pip install -r requirements.txt

Restart ComfyUI. Deps: numpy, opencv-python, scipy, torch, Pillow. No models to download. It lives under the LatLong menu.

Gotchas

Three things bite people here. First, the GPU interpolation limitation: expect bilinear even if you asked for lanczos on auto. Second, memory on very large panoramas - if you hit OOM on a 16K image, force use_tiling: enabled and drop tile_size toward 1024 rather than fighting it. Third, seam artifacts in tiled output: the overlap is currently fixed at 64px in the code, so if you see seams on stitched bands, the README's advice is to follow up with the Edge Blender node rather than trying to widen the overlap yourself.

Rotation is also the reason the rest of this pack exists - once you've reoriented a panorama, run it through the Edge Blender to kill the seam you just moved around.

CategoryLatLong

Inputs (9)

NameTypeDefaultDescription
imageIMAGEEquirectangular input image tensor (B,H,W,C) in [0,1].
yaw_rotationoptFLOAT0.0-180–180Yaw: horizontal rotation around the vertical axis (degrees).
pitch_rotationoptFLOAT-65.0-90–90Pitch: tilt up/down around the horizontal axis (degrees).
roll_rotationoptFLOAT0.0-180–180Roll: bank left/right around the view axis (degrees).
horizon_offsetoptFLOAT0.0-90–90Vertical horizon shift (degrees). Positive values move the horizon up.
interpolationoptCOMBOlanczosResampling filter used during rotation remap.
backendoptCOMBOautoProcessing backend. Auto uses GPU if available (bilinear/nearest).
use_tilingoptCOMBOautoTiled processing for 16K+ images. Auto enables for >8K images. Reduces memory usage.
tile_sizeoptINT2048512–8192Tile size in pixels for tiled processing. Smaller = less memory, more tiles.

Outputs (1)

NameTypeDescription
rotated_imageIMAGE