ComfyUI Node

Depth Warp (MEC)

The 'living photo' effect in one node — depth-driven parallax warp for 2D-to-3D motion

By Code2Collapse·Created 6 months ago·Updated a day ago· 52
Depth Warp (MEC)
  • image
  • depth
  • image
max_shift_pixels16.0
pivot0.50

You've seen the effect a thousand times: a still photo that gets subtle 3D motion - foreground sliding one way, background the other, like the camera just drifted sideways. That's depth-driven parallax, and it's exactly what DepthWarpMEC does. Give it an image and its depth map, and it shifts pixels horizontally by an amount proportional to their depth, producing the left-eye (or right-eye) view of a stereo pair. Two of these warped views, one for each eye, and you've got an actual stereo image; sequence the shift over time and you've got the classic living-photo pan.

The KB's depth-estimation doc calls this out as one of the two big uses for depth maps outside ControlNet - "3D parallax effects... the basis for all those animated living photo effects." This node is that, in ~40 lines of tensor math.

How it works

The math is a clean horizontal parallax warp. At each pixel, the shift is max_shift_pixels * (depth - pivot). Pixels shallower than the pivot value shift one way, deeper pixels shift the other, so foreground and background separate as if the camera moved. The warp uses grid_sample with bilinear interpolation, and pixels that would end up empty (where nothing got pushed into them) are filled with border replication, so you don't get black seams on the edges. Negative max_shift_pixels flips the direction - the source comment is explicit: use a negative value for the other eye. That's the entire stereo trick: warp once with +16, once with -16, and view as a cross-eye or 3D pair.

The inputs

  • image - the source.
  • depth - the depth map; it's resized to the image if the dimensions don't match.
  • max_shift_pixels (16) - how strong the parallax is. Range goes −512 to +512.
  • pivot (0.5) - the depth that doesn't move. Lower it to push the no-shift plane toward the camera.

Output is a single image.

Installing it

Part of Code2Collapse/ComfyUI-CustomNodePacks. ComfyUI Manager → search "CustomNodePacks", or:

cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git

Restart ComfyUI. Pure torch (grid_sample), no models, no extra pip packages. (Standard pack rule: skip the root pip install -r requirements.txt over ComfyUI's bundled torch/numpy.)

Gotchas

The honest limitations: this is a horizontal-only warp, so it's great for side-to-side camera moves and falls apart if you want vertical or zoom parallax. And because holes get filled with border replication, wide shifts on busy scenes show stretched or smeared edges at the frame borders - keep max_shift_pixels modest (8–24) for clean results, or crop in afterward. Your depth convention matters again: if depth is inverted relative to your expectation, foreground and background swap and the effect looks wrong - flip it at the source, not by fighting the pivot. For a quick stereo test, run the node twice with opposite shifts, or animate max_shift_pixels over frames and you've got a convincing living-photo loop.

CategoryMaskEditControl/Geometry

Inputs (4)

NameTypeDefaultDescription
imageIMAGE
depthIMAGE
max_shift_pixelsoptFLOAT16.0-512–512
pivotoptFLOAT0.500–1

Outputs (1)

NameTypeDescription
imageIMAGE