Depth Warp 6-DOF (MagicHour)
Make Your Background Pretend the Camera Moved — Real Parallax, Not a Pan
- image
- depth
- warped_image
- hole_mask
Depth Warp 6-DOF (MagicHour) is the node that takes one flat background image and re-renders it as if the camera physically moved - left, right, in, out, panned, tilted. If you've ever built a virtual studio set in ComfyUI and wished the "camera" could dolly instead of just pan, this is the missing step. A plain pan-and-tilt crop has no parallax: everything slides together like a flat postcard. This node adds real translation on top of rotation, so nearby objects shift more than distant ones, exactly like a real camera position change. That's the difference between a background and a set.
Why you'd reach for it
The author's own framing (the pack is branded "Magic Hour Inc. - Virtual Studio Background Pipeline") is multi-camera interview setups: generate one master center background, then derive the left and right camera versions from it instead of generating and regenerating. Same idea as the DepthFlow-style parallax effects the community has been playing with for years - just pointed at a specific job. It's a small, obscure pack (this node is the only one in it, one commit, basically zero community chatter as of mid-2026), so you're an early adopter either way. But it does one thing cleanly: it takes image + depth and gives you back a warped view plus a mask of everything that warp revealed.
How it works
Straight from the source, the node is honest geometry, not a model. The depth map is unprojected into a 3D point cloud - each pixel gets X, Y, Z using focal_length as your virtual camera intrinsics - the points are rotated (yaw/pitch/roll) and shifted (t_x/t_y/t_z), then perspective-projected back onto the image plane. It's a forward warp with a Z-buffer: far pixels are splatted first so near pixels overwrite them, which is what keeps overlapping geometry roughly correct. Depth is normalized to a median of 1.0 (robust to outliers) and clamped at the 5th/95th percentiles so a single hot pixel doesn't blow everything out. Where no source pixel lands - occluded regions revealed by the move - you get the hole_mask output. There's no GPU path; it's numpy + OpenCV, a couple of seconds per 1080p frame, which is fine because this is an offline background-generation step.
The inputs and outputs that matter
The image and depth inputs are the whole game: wire depth from a Depth Anything V2 node (the KB's default depth workhorse) or any depth estimator. Beyond that, three settings do 90% of the work:
t_x- lateral camera shift, the primary parameter for multi-camera setups. Positive moves right. This is what creates parallax.yaw- pan in degrees. Combined witht_xit reads as a real camera move; on its own it's just the flat pan you could already do with a crop.focal_length- higher means narrower FOV; 1200–2000 is the sweet spot for studio backgrounds.
t_y, t_z, pitch, roll are there but you'll rarely touch them (roll stays 0, t_z is basically a zoom). depth_invert defaults to True for Depth Anything V2, which outputs disparity (higher = closer); flip it False only if your depth map uses the opposite convention. mask_dilate_px (default 20) expands the hole mask a bit so your inpainter gets clean borders to work with.
Outputs: warped_image and hole_mask. The mask is the clever part - feed it straight into FLUX Fill or any inpainter to fill the revealed gaps, then you've got a clean finished background.
Installing it
Via ComfyUI Manager, search "comfyui-depth-warp", or the manual route:
cd ComfyUI/custom_nodes/
git clone https://github.com/moondive-cinema/comfyui-depth-warp.git
# restart ComfyUI
Found under MagicHour/Background. No model downloads for the pack itself - it's just numpy/torch/OpenCV, all already in a stock ComfyUI environment (there's no requirements.txt because there's nothing special to install). The real dependencies are upstream: a depth model (Depth Anything V2 via comfyui_controlnet_aux or Kijai's pack) and an inpainting model for the holes.
Where people get burned
Translation values are relative to mean scene depth, not meters - monocular depth has no absolute scale, so t_x = 0.3 means "30% of the average subject distance," tuned visually. Don't hunt for metric meaning that isn't there. Keep offsets small: the README suggests t_x 0.05–0.15 with 5–15° of yaw for talk-show setups. Push the camera too far and you're asking the geometry to invent whole regions behind foreground objects - the inpainter produces something plausible, but it's guessing. And if the warp comes out inverted (things diving instead of separating), check depth_invert first - that's the classic first-run trap.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| depth | IMAGE | — | |
| focal_length | FLOAT | 1000100–5000 | 픽셀 단위 초점거리. 화각이 좁을수록 크게. |
| t_x | FLOAT | 0.00-3–3 | 좌우 이동. 양수=오른쪽. 패럴랙스 발생. |
| t_y | FLOAT | 0.00-3–3 | 상하 이동. 양수=아래쪽. |
| t_z | FLOAT | 0.00-3–3 | 전후 이동. 양수=앞으로. 줌 효과와 유사. |
| yaw | FLOAT | 0.0-45–45 | 좌우 pan (도). 양수=오른쪽. |
| pitch | FLOAT | 0.0-45–45 | 상하 tilt (도). 양수=아래쪽. |
| roll | FLOAT | 0.0-45–45 | 회전 (도). 보통 0. |
| depth_invert | BOOLEAN | true | True: Depth Anything V2 (disparity). False: 이미 depth map. |
| mask_dilate_px | INT | 200–100 | 홀 마스크 팽창(px). FLUX Fill 인페인팅 경계 처리용. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| warped_image | IMAGE | — |
| hole_mask | MASK | — |