OA 360 Clip
Take perspective shots out of a 360° render without bending the horizon
- image
- IMAGE
The trick this node exists for: generate a 360° equirectangular image once, then slice it into multiple perspective views that all share the same background. If you've ever tried a camera pan or a "shot from a different angle" video and fought to keep the scenery consistent, this is the move - clip a forward view, a left view, a right view, and they line up because they come from the same source.
Here's the catch that makes it harder than it sounds. An equirectangular 360 image is the whole world flattened, and everything in it is curved. Grab a plain rectangular crop with a standard node and you get a bent horizon and warped architecture. OA 360 Clip undoes that curvature: it treats your flat image as a sphere and extracts a proper pinhole (gnomonic) perspective view from it, so a building in the middle of the frame stands up straight instead of bowing.
It's by "Ordinary Alan" (xordinary99 on the ComfyUI Discord), written from scratch after the license of the similar-looking ComfyUI-Olm-DragCrop wasn't permissive enough for his use. Worth knowing: if your image is not 360°, this isn't the node for you - the author's own README points you back to Olm-DragCrop for plain rectangular clipping.
How it works
The backend does the heavy lifting in oa_360_clip.py. It converts your crop's pixel coordinates to spherical latitude/longitude, converts that to a 3D direction, and samples the equirectangular map along a grid for the output - that's the gnomonic projection, and it's why a crop of the left edge and a crop of the middle both come out looking like a normal camera photo.
The crop region itself never touches your hands as numbers. A small frontend widget (1500 lines of JS) draws a draggable, resizable outline over the image preview, and pushes crop_center_x/y and crop_width/height to the backend through a tiny /oa360clip/set_crop API route. Those values are saved into the workflow's "extra" data, so your framing survives save, reload, and reopening ComfyUI. It's a genuinely fiddly integration to get right, and it mostly just works.
The inputs that matter
Only three, and you'll rarely touch the two optional ones:
- image (required) - your equirectangular 360° image as an
IMAGEtensor. Feed it from any image loader, or straight from a 360-capable model's output. - output_width / output_height - the resolution of the extracted view, both
INT. Defaults to 1280×720, range 1–8192. If you want the view at a different size than the widget's slider, wire an external integer (say, from an image size node) in; the crop preview aspect ratio follows the output dims.
The single IMAGE output is a normal ComfyUI image tensor, so it plugs into anything that takes an image - Save Image, img2img, or a paste/composite node to drop your subject onto the 360 background.
Installing it
In ComfyUI Manager, search "OA 360 Clip" and hit install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/alankent/ComfyUI-OA-360-Clip
Then restart ComfyUI. That's the entire install - there's no requirements.txt in the repo, no model files to download, nothing but PyTorch, numpy, and PIL you already have. This is one of those rare custom nodes that doesn't drag a dependency mess into your environment, which in a shared ComfyUI Python env is a real point in its favor.
Gotchas
- Run the workflow once before you can see anything. The preview only appears after the first execution loads the image, so the first thing you'll do is a run, then drag the outline. This trips up everyone, the README calls it out explicitly.
- Stay away from the poles. The README and the code both warn: crops near ±90° latitude get severe gnomonic distortion. The code caps crop width at 25% of the input width and clamps FOV at 170° precisely to keep you out of the ugly zone; heed the "severe distortion" warning it prints to the console.
- Horizontally, the crop wraps. Equirectangular images are a cylinder - drag past the right edge and you continue on the left. Confusing for a second, actually the right behavior.
- Batch in, batch out. Feed it a batch of 360 frames and it repeats the extracted view to match - handy if you're processing more than one.
Small and honest, this one. It does exactly one job - un-curving perspective crops from 360 renders for consistent backgrounds - and does it without dependencies or model downloads. If you're making camera moves over a shared 360 background, it's the node you'll reach for.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| output_widthopt | INT | 12801–8192 | — |
| output_heightopt | INT | 7201–8192 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |