Nodes/ComfyUI libigl/Depth Map to Mesh
ComfyUI Node

Depth Map to Mesh

Turn a depth map or mask into an actual mesh

By PozzettiAndrea·Created 10 months ago·Updated 4 days ago· 218
Depth Map to Mesh
  • mask
  • depth_image
  • field
  • mesh
  • info
height_scale1.0
backend
field_namefield
invert_heightfalse
skip_blackfalse
black_threshold0.01

Depth Map to Mesh is the node that turns a 2D heightmap into an actual 3D surface you can remesh, unwrap, print, or light. It's the classic "make geometry from an image" trick, and it's where a ComfyUI workflow stops being about pixels and starts being about polygons. Run a depth estimator on a photo, feed the result here, and you get a TRIMESH out the other side.

How it works

You give it a mask or a depth_image - brightness becomes height. Darker pixels sit low, brighter pixels stand tall (flip it with invert_height if your map is backwards). Then a backend turns that heightfield into triangles:

  • grid (default) - a fast, regular grid of vertices displaced by the heightmap. Instant, but you can see stair-stepping on steep slopes.
  • poisson - Screened Poisson reconstruction through PyMeshLab or Open3D. Smoother, and you can raise backend.poisson_depth (4–12, default 8) for more detail at the cost of time.
  • delaunay - 2D Delaunay triangulation of the sampled points.

Two options beginners miss: skip_black deletes faces near pure-black pixels (set black_threshold, default 0.01) - that's your free trim tool when your mask has a black border. And field lets you stash an extra mask as a vertex attribute named by field_name, which is handy if you want to carry face IDs or curvature through to a later node.

The inputs and outputs

  • height_scale (0.01–10, default 1) - vertical exaggeration. The one knob that changes the whole character of the result. 1 is literal; bump it to make a relief look dramatic.
  • mask / depth_image - you need at least one; if you feed an image, the RGB channels get averaged to grayscale.
  • Outputs: mesh (TRIMESH) and info (STRING with stats).

The mesh wires straight into GeomPackCreatePrimitive-style downstream nodes - Save Meshes to Folder, Preview Mesh, Remesh, whatever. This is the bridge from "depth estimation" workflows into the geometry side of the pack.

Installing it

Same as any GeometryPack node - it ships in ComfyUI-GeometryPack, so:

cd ComfyUI/custom_nodes
git clone https://github.com/PozzettiAndrea/ComfyUI-GeometryPack.git
cd ComfyUI-GeometryPack
pip install -r requirements.txt --upgrade
python install.py

Or ComfyUI Manager → search GeometryPack → Install (highest version, nightly if that fails). Restart ComfyUI after. This is a main-env node, so it's one of the lighter installs in the pack - the poisson path pulls in PyMeshLab/Open3D, but you skip the heavy Blender/CGAL environments this pack otherwise sets up.

Where people get burned

The grid backend's stair-stepping is the top gotcha - if your result looks like a topographic map made of bricks, switch to poisson and give it a couple more octree levels. And remember the height direction: a depth map from one estimator may be "inverted" relative to another, which is exactly why invert_height exists. When the surface comes out looking hollowed rather than raised, that's the first thing to try. Also: everything this pack produces wants the right input type - feed it a proper IMAGE or MASK from a depth node, not a screenshot of a depth map, or the values will be off and your relief will look mushy.

Categorygeompack/texture_remeshing

Inputs (9)

NameTypeDefaultDescription
height_scaleFLOAT1.00.01–10
backendCOMBOReconstruction backend: grid (fast), poisson (smooth), delaunay
maskoptMASK
depth_imageoptIMAGE
fieldoptMASKOptional field to store as vertex attribute on the mesh (e.g., face IDs, curvature)
field_nameoptSTRINGfieldName for the vertex attribute
invert_heightoptCOMBOfalse2 options: false, true
skip_blackoptCOMBOfalseSkip faces connected to near-black pixels in the depth map
black_thresholdoptFLOAT0.010–1Threshold below which pixels are considered black (only used when skip_black is true)

Outputs (2)

NameTypeDescription
meshTRIMESH
infoSTRING