Nodes/ComfyUI-DukeStereo/Duke Stereo Video (SBS)
ComfyUI Node

Duke Stereo Video (SBS)

Make your flat ComfyUI video actually 3D in a VR headset

By killertofu86·Created 7 months ago·Updated 7 months ago· 0
Duke Stereo Video (SBS)
  • images
  • depth_maps
  • video_path
output_path/ComfyUI/output/stereo_%date:yyyy-MM-dd%_%time:HH-mm-ss%.mp4
fps24
divergence2.5
separation0.0
convergence_point1.00
stereo_offset_exponent2.0
fill_technique
depth_blur6
depth_blur_edge_threshold6.0
crf19

You've got a nice generated video sitting in your ComfyUI workflow, and you want to actually watch it with depth on a VR headset. This is the node for that specific job: it takes your video frames plus a matching depth map per frame, warps them into left-eye and right-eye views, and writes a side-by-side (SBS) MP4 that VR players will happily play. Nothing gets sent anywhere, no API key, no cloud converter - it's all local math over your own frames.

The pipeline it fits into is straightforward: load a video, run a depth estimator (the README suggests LeReS or similar; the KB's depth-estimation essay covers the usual suspects), and hand both the frames and the depth maps to this node. That's the whole deal - one output node that both warps and encodes. This is a genuinely rare capability in ComfyUI: most of the ecosystem's stereo work is still done with standalone tools like iw3 (nunif) or owl3d, so if you want to stay in the graph this is one of the few native options.

How it actually works

For every frame, the node does three things. First it blurs the depth map with an edge-aware blur (depth_blur with depth_blur_edge_threshold), so depth flicker is smoothed out without smearing object silhouettes. Then it warps the image twice using the depth map to shift pixels - once at +divergence for the left eye, once at -divergence for the right - and stitches the two results side by side (so the output is double the input width). Finally it pipes those frames straight into ffmpeg through a background writer thread, encoding H.264/yuv420p, which is exactly the format VR players want.

The RAM efficiency is real: frames stream into a bounded queue and get written out as they're produced, so a 30-second clip doesn't balloon your memory like stacking every SBS frame in a tensor would. It also auto-scales your depth maps to the frame size, tolerates single- or three-channel depth, and rescales 0–1 depth to 0–255 for you - the node is more forgiving about input format than most of this ecosystem.

The one thing to know before you get excited: this is "stereo from a single view," which means the depth map can't see around objects. Push divergence hard and you'll expose seams and occluded background that no fill technique can truly invent. As the depth-estimation doc puts it, motion has to stay subtle or the image starts tearing.

The inputs that matter

  • images and depth_maps - your frames and one depth map per frame. Everything starts here.
  • divergence (default 2.5) - the 3D strength. Higher = more depth, more artifacts. This is your main dial.
  • convergence_point (0–1) - where the zero-parallax plane sits. Crank toward 1.0 and depth pops behind the screen; near 0 and it comes out toward you.
  • fill_technique - polylines_soft (default), polylines_sharp, naive, or none. The polylines methods are the high-quality gap fillers for the seams warping creates; naive is fast and crude, none leaves holes.
  • output_path - supports format strings like %date:yyyy-MM-dd%, %time:HH-mm-ss%, %divergence%, %width%x%height%, plus ~ expansion and automatic _001 suffixing when the file exists.

It returns a single video_path (STRING) - the full path to the MP4 it wrote, which you can display in the UI to confirm where your file landed. fps and crf control encoding (lower crf = better quality); separation adds a manual horizontal offset on top of the depth-driven one; stereo_offset_exponent (default 2.0) shapes the non-linear depth curve.

Installing it

Via ComfyUI Manager, search "ComfyUI-DukeStereo" and install. Or by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/killertofu86/ComfyUI-DukeStereo.git
pip install -r ComfyUI-DukeStereo/requirements.txt

Then restart ComfyUI. A couple of real gotchas: ffmpeg has to be on your PATH as a system binary (the README lists it as a requirement but it's not in requirements.txt, and the node shells out to it), and transformers sits in requirements.txt but the shipped code never imports it - it's vestigial, leftover from an earlier version. This node does not estimate depth for you; you must supply the depth maps.

Common issues

The default output_path is /ComfyUI/output/..., an absolute path that doesn't exist on most installs. Change it - it's the first thing that'll bite. The node creates the directory and checks write permission up front, but if ffmpeg isn't installed the writer thread fails, and the error can be easy to miss. And be patient on the first run: numba JIT-compiles the warp kernels, so the first execution can feel sluggish before it warms up. If tearing appears in your output, back the divergence down before you blame the node.

CategoryStereo

Inputs (12)

NameTypeDefaultDescription
imagesIMAGE
depth_mapsIMAGE
output_pathSTRING/ComfyUI/output/stereo_%date:yyyy-MM-dd%_%time:HH-mm-ss%.mp4
fpsINT241–120
divergenceFLOAT2.50–50
separationFLOAT0.0-5–5
convergence_pointFLOAT1.000–1
stereo_offset_exponentFLOAT2.00.1–4
fill_techniqueCOMBO4 options: polylines_soft, polylines_sharp, naive, none
depth_blurINT60–50
depth_blur_edge_thresholdFLOAT6.00–50
crfINT190–51

Outputs (1)

NameTypeDescription
video_pathSTRING