πͺ π Stereoscopic 3D Generator
Turn a flat render into cross-eye 3D (and the silent fallback that will fool you)
- image
- depth_map
- stereogram
- left_eye
- right_eye
- depth_map
Stereo 3D is a niche of a niche - anaglyph questions show up maybe six times a year. Be honest about why you'd install this: you own red-cyan glasses, or a VR viewer, or you want a cross-eye image that looks like it's floating.
SaturnStereo3D takes one 2D image and fakes a camera rig out of it, using monocular depth estimation - a grayscale map where brightness encodes distance. The community settled on Depth Anything V2 for that back in 2024 and nothing has displaced it since: V2 Large for ControlNet, V2 Small when you want speed. Small is the weight this node reaches for.
How it actually works
This is DIBR - depth-image-based rendering, the same idea behind every "living photo" parallax tool, minus the animation. Each pixel shifts horizontally by (depth - convergence_plane) * max_shift, where max_shift is depth_intensity / 100 * 3.5% of image width; the image is then warped twice through that field.
Three things fall out of that math:
- Intensity is subtle by design. At the default 25 you shift pixels by under 1% of the width; at 100 you cap at 3.5%. Push past what the depth map supports and you get tearing and smeared edges, not more depth - the wall everyone hits with depth-based parallax.
- Occlusions aren't inpainted. Where the warp reveals pixels that weren't in the source, the node grabs the nearest border pixel - no LaMa, no diffusion fill. Hard vertical edges smear sideways when you crank it.
- Convergence is your focus knob. Depths equal to
convergence_planedon't move at all - that's the screen surface. Raise it and more pops out; lower it and more sinks away.
With no depth_map wired in, the node runs Depth Anything V2 Small itself: letterbox to 518Γ518, ImageNet normalization, p2/p98 normalization back to full resolution. The model is ~94 MB and downloads on first run into ComfyUI/models/depth/depth-anything-v2-small-518.onnx. Predictions are cached in-process, so a repeat run on the same image is fast.
The inputs that matter
image and mode come first. mode picks the format: Cross-Eye, Parallel (Wall-Eyed), Red-Cyan Anaglyph, Side-by-Side (Parallel), Top-Bottom (Over-Under), or a single eye. Cross-eye swaps the panels - the left half is the right eye's view - which is why the wrong choice from that dropdown makes your eyes hurt instead of converge.
Then it's depth_intensity, convergence_plane, depth_gamma (default 0.50; below 1.0 fattens the near plane so more reads as close), and invert_depth if your map is upside down. image_zoom, pan_horizontal and pan_vertical crop into the frame before disparity is computed - how you make a subject sit proud of its background. gap_spacing and outer_border apply only to the side-by-side and over-under layouts - framing, and your "shrink it so crossing your eyes is easier" knob. alignment_dots drops white focus dots above each panel so you can lock in.
Four outputs: stereogram, left_eye, right_eye, and depth_map - the normalized map it used. This isn't an output node, so nothing shows until stereogram hits a Preview or Save Image. The depth_map output is quietly the most useful: a ControlNet-ready depth map for the rest of your graph.
One quirk: preview_zoom has a tooltip about scaling the canvas preview, but nothing in the shipped 2.5.0 code reads it. Moving it won't do anything yet.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/KOFiblto/ComfyUI-SaturnNodes
Or search "SaturnNodes" in ComfyUI Manager, then restart. requirements.txt is just Pillow, piexif and numpy - no install.py, no runtime pip calls.
For this node specifically, add the one it needs:
pip install onnxruntime # or onnxruntime-gpu for CUDA
Where people get burned
No onnxruntime means no real depth. It's commented out in requirements.txt as optional, and the failure mode is nasty: instead of erroring, the node prints a console notice and generates a pseudo-depth map - a vertical gradient blended with luminance, brighter at the bottom. Your stereogram comes out vaguely three-dimensional and completely wrong, and if you never open the console you'll spend an evening blaming your sliders. If the effect reads as a flat tilt rather than a scene, that's what happened.
Air-gapped installs. The download tries Hugging Face, then a mirror, and raises Failed to download Depth Anything V2 Small ONNX model if both fail. Pre-place the file at ComfyUI/models/depth/depth-anything-v2-small-518.onnx - the >10 MB size check means a truncated file gets fetched again.
Your own depth map must be white = near. That's Depth Anything's convention and what the node assumes; ControlNet preprocessors differ. If the scene comes out inside-out, that's invert_depth, not a broken node.
Depth is computed at 518Γ518, then warped onto your render. Fine around 1024 pixels; past that the depth edges are softer than your image edges, and no amount of intensity fixes it.
Every tweak is a re-queue. No live preview in this node, so budget a few iterations rather than expecting a slider to update on canvas.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | β | |
| mode | COMBO | Cross-Eye | 7 options: Cross-Eye, Parallel (Wall-Eyed), Red-Cyan Anaglyph, Side-by-Side (Parallel), Top-Bottom (Over-Under), Left Eye Only, +1 |
| depth_intensity | FLOAT | 250β100 | Controls how much the left and right perspectives shift apart. |
| depth_gamma | FLOAT | 0.500.1β3 | Adjust depth curve for realistic 3D falloff (Stereonix default is 0.50). |
| invert_depth | BOOLEAN | false | Flip which parts appear closer or further away. |
| convergence_plane | FLOAT | 0.500β1 | Depth level where parallax is zero (screen surface). Above pops out, below sinks in. |
| image_zoom | FLOAT | 10010β300 | Zoom into areas of interest before generating 3D disparity. |
| pan_horizontal | FLOAT | 0-100β100 | Horizontal pan offset (-100 to 100). |
| pan_vertical | FLOAT | 0-100β100 | Vertical pan offset (-100 to 100). |
| gap_spacing | INT | 200β1000 | Empty black space between the left and right images. |
| outer_border | INT | 00β1000 | Black border padding around the canvas (allows shrinking images for easier cross-eye viewing). |
| alignment_dots | BOOLEAN | true | Place focus guide dots above each eye view to easily lock into 3D cross-eye view. |
| fill_method | COMBO | Smooth (Bilinear Grid) | Hole-filling interpolation for occlusion gaps. |
| preview_zoom | COMBO | 50% | Scale preview for easier cross-eye viewing on canvas (does not affect full output). |
| depth_mapopt | IMAGE | Optional depth map. If disconnected, automatically runs Depth Anything V2. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| stereogram | IMAGE | β |
| left_eye | IMAGE | β |
| right_eye | IMAGE | β |
| depth_map | IMAGE | β |