Export Depth Mesh (GLB)
Turn a flat photo's depth into a real GLB mesh you can drop in Blender — no extra packages, no servers
- depth_map
- color_image
- glb_paths
- manifest_json
A depth map is a height field in disguise, and a height field is a 3D model waiting to happen. Export Depth Mesh (GLB) is the node that does the conversion: it takes your depth map - optionally dressed in the original photo's colors - and writes an actual, standards-compliant glTF 2.0 binary mesh to disk. Bas-relief plaques, displacement geometry, rough preview geometry for a scene, game-asset starting points: this is the bridge between "flat image plus depth" and "object you can orbit in Blender." It's the same pack as the rest of gokayfem's ComfyUI-Depth-Visualization toolkit, and like them it's aggressively offline - no trimesh, no assimp, no cloud conversion service.
How it works
Under the hood it's a clean pinhole camera projection. Your depth values become Z, and X and Y are computed from pixel position scaled by a focal length derived from field_of_view - so the mesh comes out in genuine camera space, not a naive image grid. stride controls how many pixels get skipped when building the vertex grid: 4 means every fourth pixel becomes a vertex, which is your resolution slider. Bigger stride = lighter mesh, but you trade geometric detail and risk running out of vertices.
Then the interesting part: max_edge_length culls triangles whose edges exceed the threshold. This is what keeps depth discontinuities from turning into one giant stretched triangle spanning from a foreground nose to the horizon. Set it to 0 to disable culling entirely (fast, ugly), or keep the default 0.15 to drop those spanning faces.
The GLB writer is hand-rolled - it packs positions, colors, and indices into buffer views and accessors with struct.pack, writes the JSON chunk, and assembles a valid binary glTF. No magic, no dependencies beyond numpy and Pillow.
Inputs and outputs that matter
depth_map- in. Normalize it first;depth_scale(default 1) then multiplies depth values into real-world-ish units.field_of_view(60) - the virtual camera's FOV. Match the source if you know it.depth_scale- how deep the mesh is. 1 = depth values map 1:1. This is your "extrude the relief" knob.stride(4) - vertex grid sampling. Lower = denser mesh.max_edge_length(0.15) - triangle culling at depth jumps.filename_prefix(depth_exports/depth_mesh) - where files land inside ComfyUI's output folder.color_image(optional) - the original photo; the mesh gets vertex colors. Skip it and the node colors by depth instead.
Two outputs, both strings: glb_paths (newline-joined file paths) and manifest_json (paths, triangle counts, and the settings that produced them). The node is an output node - it writes to ComfyUI/output/ automatically, timestamped so you never overwrite a previous export.
Install
ComfyUI Manager, search ComfyUI-Depth-Visualization, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/gokayfem/ComfyUI-Depth-Visualization.git
python -m pip install -r ComfyUI-Depth-Visualization/requirements.txt
Restart; the node lives under depth/3D export. No models to download, no CUDA needed - it's deterministic CPU math.
Where people get burned
- "No valid mesh triangles remain" - your
max_edge_lengthis too small orstridetoo large; the culler killed everything. Raise the threshold or drop the stride. - "stride is too large for this depth-map resolution" - you've asked for a grid with fewer than 2×2 vertices. Lower
stride. - Holes become volcanoes. If your depth has zero-gaps, the mesh grows through them. Run Clean & Repair Depth first - it's in the same pack, built for exactly this.
- Un-normalized depth = nonsense scale. Feed raw 0–47 range into
depth_scale1 and you get a spike 47 units tall. Depth Normalize to[0,1], then usedepth_scaledeliberately.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| depth_map | IMAGE | — | |
| field_of_view | FLOAT | 601–179 | — |
| depth_scale | FLOAT | 1.000.001–1000 | — |
| stride | INT | 41–64 | — |
| max_edge_length | FLOAT | 0.150–1000 | — |
| filename_prefix | STRING | depth_exports/depth_mesh | — |
| color_imageopt | IMAGE | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| glb_paths | STRING | — |
| manifest_json | STRING | — |