360 Projection
Turn equirectangular 360 footage into a normal-looking shot, or re-point it
- video
- video
A 360° camera gives you the whole world at once, which is also its problem: you can't watch the world at once. The equirectangular frame is that squashed, stretched sphere, and everything you actually want to see lives in some sub-window of it. 360 Projection is the ComfyTV stage that unwraps it - it re-projects equirect footage into a flat view, and lets you re-aim that view with yaw, pitch, and roll as if you were turning your head after the fact.
It's a VideoFX stage in the pack's canvas: own Run button, snapshot output, and it rides the FX-chain system so you can stack it with other effects and render once.
The inputs that matter
- proj_in (default
equirect) and proj_out (defaultflat) - the projection change. Feed it equirect footage and ask for flat, and you get a conventional rectilinear-looking frame. - v360_yaw, v360_pitch, v360_roll (−180 to 180) - where the virtual camera points. This is the "look around the sphere" control, and it's how you frame the shot you want out of the 360 capture.
- v360_fov (0–360, default 0) - output horizontal field of view; the tooltip says 0 = default. A wide fov is a wide angle look, low fov is a zoomed-in peek.
- v360_interp (default
cubic) - the resampling for the re-projection; cubic is a fine default.
The project_id / parent_output_id / force_run_token inputs are internal frontend plumbing - ignore them.
How it works
This is a wrapper around FFmpeg's v360 filter, which does the spherical-to-planar math. The node builds the filter string from your inputs - input=equirect, output=..., interpolation, and any non-zero yaw/pitch/roll, plus horizontal and vertical FOV (it derives vertical from fov * 9/16 to keep your aspect ratio honest). Handy detail: if proj_in equals proj_out and there's no rotation or FOV change, the node returns the video untouched - an identity passthrough - so wiring it into a pipeline "just in case" doesn't cost you a re-encode.
Install
ComfyTV ships ~190 stages in one pack; installing the pack gives you this node.
cd ComfyUI/custom_nodes
git clone https://github.com/jtydhr88/ComfyTV
Restart ComfyUI (fully - not a browser refresh) and find it under ComfyTV → VideoFX. ComfyUI Manager also finds it by searching "ComfyTV". No model downloads, no extra Python deps. On ComfyUI Desktop or macOS, clone into the running instance's absolute path from the startup log instead of trusting the relative cd.
Troubleshooting
- Output looks the same as input. Either your footage wasn't actually equirectangular, or in==out with no motion means the identity passthrough kicked in. Change
proj_outand set some yaw to see movement. - Distorted at the edges. That's the nature of re-projecting a sphere onto a flat plane - a wider FOV shows more of the inherent stretching. Narrow the FOV for a more natural look.
- No output. Wire a video into the
videoinput first.
If your workflow ever touches 360 footage, this plus 360 Stabilize is the pair you'll reach for - project to flat, then stabilize what you've aimed at.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| force_run_token | INT | 00–2147483647 | Internal — bumped on Run to invalidate ComfyUI's input cache. |
| project_id | STRING | Internal — populated by the projectStore on the frontend. | |
| parent_output_id | INT | 00–2147483647 | Internal — lineage parent set by spawn handlers on the frontend. |
| proj_in | COMBO | equirect | 11 options: equirect, flat, fisheye, dfisheye, sg, eac, +5 |
| proj_out | COMBO | flat | 11 options: equirect, flat, fisheye, dfisheye, sg, eac, +5 |
| v360_yaw | FLOAT | 0-180–180 | — |
| v360_pitch | FLOAT | 0-180–180 | — |
| v360_roll | FLOAT | 0-180–180 | — |
| v360_fov | FLOAT | 00–360 | output horizontal FOV, 0 = default |
| v360_interp | COMBO | cubic | 4 options: linear, cubic, lanczos, nearest |
| videoopt | COMFYTV_VIDEO | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video | COMFYTV_VIDEO | — |