Nodes/comfyui-dap/DAP Panoramic Mesh
ComfyUI Node

DAP Panoramic Mesh

Turn a 360° photo into a mesh you can walk around in

By maxious·Created 8 months ago·Updated 8 months ago· 1
DAP Panoramic Mesh
  • depth
  • image
  • mask
  • mesh
mesh_scale1.0
downsample1
remove_long_edges0.10
max_depth_cutoff0.99
stitch_seamtrue

This is the payoff node of the pack. DAP Panoramic Mesh takes the depth map from DAP Inference and unprojects it onto a sphere, producing an actual 3D mesh of your 360° scene. Not a flat relief, not a heightfield - a closed, walk-around-you surface where the wall that wraps around the seam stays connected.

That's the whole reason the DAP model exists. A flat depth model on an equirectangular image gives you a sheet with a torn seam and pinched poles; because this depth map respects sphere topology, the mesh it produces is a genuine spherical room. This is the "I made 3D 360 VR panoramas" trick made local and node-based.

How it works

Every pixel of the depth map is turned into a 3D point: the pixel's position in the equirect map is converted to a direction on a unit sphere (via the standard equirectangular UV mapping), then pushed outward by the depth value times mesh_scale. Adjacent points get connected into a triangle grid. Two details are worth knowing about because they're the difference between a mesh and garbage:

  • Pole snapping - the top and bottom rows of the sphere are averaged into a single point so the poles pinch cleanly instead of fanning into spikes.
  • Seam stitching - the right edge is bridged back to the left edge, closing the sphere. That's what makes it a walk-around surface rather than a tube.

Then it runs optional cleanup passes. With max_depth_cutoff at its default 0.99, faces beyond that depth (read: sky and far-away infinity) get culled. remove_long_edges deletes faces with edges longer than a threshold, which kills the streak artifacts you get at low resolution. A mask input removes faces that fall outside it.

Inputs that matter

  • depth - required; the IMAGE output of DAP Inference.
  • mesh_scale - default 1.0. Multiplies how far each vertex is pushed. Raise it to make the room bigger; lower it to compress. It's just a scalar on depth.
  • downsample - default 1. Crank to 2+ and it samples every Nth pixel, cutting vertex count dramatically. Start here if the node is slow or eats VRAM; expect blockier geometry.
  • image (optional) - wire your original panorama in and it becomes vertex colors on the mesh. Free texture pass, hugely worth it for previews and exports.
  • mask (optional) - from DAP Inference, so boundary junk and sky you already masked out don't get meshed.

The output

mesh, a TRIMESH - a trimesh.Trimesh object. That's a deliberate interop choice: this pack is compatible with ComfyUI-GeometryPack, so you can pipe the mesh straight into a decimator, boolean operations, or a 3D exporter instead of being stuck with whatever this pack offers. If you want to actually see it, you need one of those downstream nodes.

Install and gotchas

Same drill as the rest of the pack: clone with --recursive (the model lives in a git submodule), pip install -r requirements.txt into the ComfyUI venv. This node is one reason that dependency list is heavy - trimesh and friends come along with the pack.

Where people get burned:

  • Sky becomes a dome of far garbage - the max_depth_cutoff default handles it, but if you raise it toward 1.0 to keep sky, raise remove_long_edges too or you'll get long streaky triangles.
  • Out of memory - a full-res depth map meshed at downsample=1 is a lot of triangles. Use downsample=2 first, then decide if you need more.
  • Mesh looks "inside out" - depth maps put the camera at the center, so you're viewing the inside of a room, which is exactly right for a 360° capture. That's not a bug.

It's the node that makes all the panorama-specific work feel worth it. Feed it a good DAP depth map and you get geometry you can actually orbit around.

CategoryDAP/Geometry

Inputs (8)

NameTypeDefaultDescription
depthIMAGE
mesh_scaleFLOAT1.00.01–100
downsampleINT11–8
imageoptIMAGE
maskoptMASK
remove_long_edgesoptFLOAT0.100–2
max_depth_cutoffoptFLOAT0.990.1–1
stitch_seamoptBOOLEANtrue

Outputs (1)

NameTypeDescription
meshTRIMESH