Nodes/atlas-camera/Atlas Derive Relief Mesh πŸ”
ComfyUI Node

Atlas Derive Relief Mesh πŸ”

A ComfyUI node in Atlas/05 Β· Geometry with 20 inputs and 3 outputs.

By mikejamesvfxΒ·Created 2 months agoΒ·Updated about 23 hours agoΒ· 1
Atlas Derive Relief Mesh πŸ”
  • solve
  • depth
  • exclude_mask
  • outlier_mask
  • solve
  • hole_mask
  • report
β—„relief_grid128β–Ί
β—„relief_qualitycustomβ–Ί
β—„depth_edge_rel0.50β–Ί
β—„max_edge_factor12β–Ί
β—„sky_heuristictrueβ–Ί
β—„normal_edge_deg0β–Ί
β—„quad_coherencetrueβ–Ί
β—„sub_quad_boundaryfalseβ–Ί
β—„silhouette_mattefalseβ–Ί
β—„soft_visibilityfalseβ–Ί
β—„transition_ribbonfalseβ–Ί
β—„ribbon_px64β–Ί
β—„ribbon_bend-0.30β–Ί
β—„ribbon_adaptivefalseβ–Ί
β—„ribbon_depth_slope2.00β–Ί
β—„ribbon_smudge_px12β–Ί
CategoryAtlas/05 Β· Geometry

Inputs (20)

NameTypeDefaultDescription
solveATLAS_SOLVEβ€”
depthATLAS_DEPTH_MAPβ€”
relief_gridoptINT12816–4096Mesh density (long-edge grid columns). Higher = fewer/smaller torn holes on noisy AI-image depth, at the cost of a larger mesh payload and a heavier viewport.
relief_qualityoptCOMBOcustomQuick-pick override for relief_grid: low=64, medium=256, high=512, ultra=1024. 'custom' leaves relief_grid as set above.
depth_edge_reloptFLOAT0.500.05–5Relative depth jump that tears the mesh into a silhouette hole. Lower = tears more readily; higher = tears less but risks rubber-sheeting a real silhouette onto the background.
exclude_maskoptMASKOptional external exclusion (e.g. a real sky segmentation from AtlasSAM3Mask) which REPLACES the internal sky heuristic before triangulation - so it must cover EVERYTHING you want gone. Any resolution - resized to match depth. MIND THE POLARITY: masking the BACKGROUND meshes the hero alone and repairs its own tears; masking the SUBJECT leaves a subject-shaped hole and repairs BEHIND it. For the second, just name BOTH in one AtlasSAM3Mask - `concepts` is already a union, so "sky, machinery" masks sky AND subject in one node (no MaskComposite needed); this input replaces the heuristic, it does not add to it. Check the segmenter's report: SAM3 is open-vocabulary and the WORD decides everything - on one real plate "machine" matched nothing while "machinery" took 26.8% of frame.
outlier_maskoptMASKOptional local depth outlier mask from AtlasDepthOutlierMask. Those cells become explicit holes instead of stretched shards.
max_edge_factoroptFLOAT122–200World-space edge tear threshold: a quad tears when its world edge exceeds this x the expected local sample spacing. SEPARATE from depth_edge_rel, and often the DOMINANT tear cause on deep / narrow-FOV / interior scenes, where grazing walls and receding floors span large world distances between adjacent samples and trip the default 12x even where the surface is continuous. Raise (20-40) to close spurious 'comb' tears; too high (>80) rubber-sheets real foreground silhouettes onto the background.
sky_heuristicoptBOOLEANtrueExclude above-horizon far/rough regions as sky before triangulation. Correct for OUTDOOR plates; turn OFF for INTERIORS (it otherwise eats the ceiling / vault / far wall as 'sky', punching large holes). Automatically off when exclude_mask is wired (an explicit mask always governs).
normal_edge_degoptFLOAT00–1800 = off. When set, a THIRD tear test: a triangle tears when its corner surface-normals bend by more than this angle. Unlike max_edge_factor (which trips on ANY grazing/receding surface), this fires only where the surface ORIENTATION changes sharply - a real crease or occlusion silhouette - so it tears genuine edges while leaving a smoothly-receding wall/floor intact. Pair it with a HIGHER max_edge_factor: raise mef to stop comb-tearing continuous grazing surfaces, then set ~40-70 here to keep real silhouettes torn. Lower = tears more readily.
quad_coherenceoptBOOLEANtrueReject both triangles when either half of a grid quad fails. Prevents one surviving diagonal from becoming a stretched UV wedge.
sub_quad_boundaryoptBOOLEANfalseCut a torn cell AT the depth cliff instead of deleting the whole cell. Tearing is per grid cell, so a silhouette can only turn in whole-cell steps AND a cell of real surface is lost on both sides of every cliff - measured 5.67px mean boundary error at grid 128 on a 1024px plate (step 8px), i.e. WORSE than the 4px quantization bound. This finds the cliff in the full-resolution depth and rebuilds each side up to it, never joining them: 5.67 -> 1.43px, and 1.35px with boundary_smooth_iterations on top. Costs ~5% more vertices (it scales with silhouette LENGTH, not mesh area). The tear itself is untouched - same thresholds, same cells torn.
silhouette_matteoptBOOLEANfalseCut the SKY/EXCLUSION silhouette per-pixel in the viewport instead of at grid resolution. Grows a boundary skirt outward (edge_overhang_cells, defaulted to 2) and ships a full-resolution matte the projection shader cuts it back with - measured strip uncovered 0.083 -> 0.000 with ZERO pixels spilled into the sky, and the matte's edge tracks the true skyline to 0.25px against 4px lattice quantization. The skirt and the matte are ONE switch on purpose: an unmatted skirt carries replicated sky pixels on receding geometry (found live on monument valley). Does NOT help depth-cliff staircases - at a cliff both sheets share a pixel, so one matte cannot keep one and cut the other; that is sub_quad_boundary's job.
soft_visibilityoptBOOLEANfalseSOFT LAYERING (SLIDE, ICCV 2021) - the viewport answer to sawtooth silhouettes. Instead of TEARING at a depth cliff and leaving a hole to feather, keep the surface continuous (it rubber-bands across the cliff) and fade those fragments with a per-pixel visibility A = exp(-beta*|grad disparity|^2) computed at PLATE resolution. No tear means no boundary to quantize, so there is no staircase at ANY grid - and the lattice stays intact, so planar hole patch and the CUDA repair keep working (unlike sub_quad_boundary, which this supersedes and disables). Measured on a diagonal cliff: fade to 0.039 over a 4px feather while smooth receding ground stays at 0.987. Needs something BEHIND to reveal (BG clean-plate / sky dome / clean_plate input) or the fade shows the backdrop. Export still tears - a DCC has no shader to fade with.
transition_ribbonoptBOOLEANfalseKEEP the tear and hang a bounded skirt off it. soft_visibility's alternative is to delete the tear, which lets every cliff cell stretch into a fin whose length is set by the depth jump and by nothing else (the long straight slabs seen off rooflines). This grows separate topology from the open rim: each rim vertex spawns its own column of vertices stepping outward in IMAGE space, so the skirt's apparent width is a fixed pixel count at ANY scene depth. Not an extrusion along the view ray - under a pinhole camera every point on a ray projects to the SAME pixel, so a ray extrusion has exactly zero screen width. UVs freeze at the silhouette texel, making this an edge-extend CLAMP with no stretch, and the fade rides the geometry as a per-vertex parameter, so the GLB export carries the same curve the viewport shows. Shares no vertex with the foreground - the tear survives topologically. Mutually exclusive with soft_visibility, which leaves no rim to hang off. Do NOT combine with sub_quad_boundary: measured on a real plate at grid 256 its fractional-pixel rim is 6x longer (49846 vs 8286 edges), so the skirt costs 5.8x the mesh (383k vs 66k vertices) for the SAME achieved width and folds worse (8% of quads dropped vs 1.5%). Needs a behind-layer to reveal, like any fade.
ribbon_pxoptFLOAT640–400Transition-ribbon width in SCREEN pixels of the SOURCE PLATE, measured in the recovered camera. Constant apparent width is the point: near objects do not get thick skirts and far ones do not collapse to nothing. It is the single length control - the skirt's depth run is capped to a multiple of its own world width, so its 3D length under orbit scales with this too (measured on a 7680px plate: 32px -> 0.10m median, 128px -> 0.40m). Scale it with the PLATE, not the screen: 40-64 suits a 2K plate, and the same apparent size on a 7680px plate needs ~150-240. Achieved width is measured back through the camera as stats.transition_ribbon.measured_px_p50/p95; world length is reported as world_len_p50_m/p95_m.
ribbon_bendoptFLOAT-0.30-0.5–0.5Shape of the depth falloff, and the SIGN is the control. NEGATIVE curls away from camera fast and then levels off - the tight inward lip; -0.5 is the tightest. 0 is a straight linear ramp. POSITIVE dwells at silhouette depth and then dives, which reads as a flat flange sticking outward before it drops. Limited to +/-0.5 because the ramp is only monotonic in that range: outside it the skirt starts (or ends) moving back TOWARD the camera and folds through the surface it hangs off. To make the skirt SHORTER, lower ribbon_px - bend changes its shape, not its length.
ribbon_adaptiveoptBOOLEANfalseScale ribbon_px by how big the discontinuity actually is, relative to depth_edge_rel and clamped 0.5x-2x. DEFAULTS OFF, and the measurements are why: on a castle exterior it was the only setting that broke width consistency (p95 85px against a requested 64) and it produced the highest fold-clamp rate of any configuration (25.6% of columns, against 18-21% with it off). The idea is sound - big occlusions want more transition - but in practice it trades a predictable skirt for an uneven one. Turn it on only if you specifically want wide occlusions to get extra room and can accept the variance.
ribbon_depth_slopeoptFLOAT2.000.25–8How far the skirt may RECEDE, as a multiple of its own world width. This is the second length control and the one that governs what an ORBIT sees: bounding ribbon_px alone bounds only the recovered camera's view, and the depth run used to reach the inferred background unchecked - measured on a 7680px plate, a ~1m wide skirt ran 15m deep, invisible head-on and an enormous tube off-axis. Low (0.5-1) is a thin flat membrane that hugs the silhouette; high (4-8) lets it reach further back toward real background at the cost of long slabs under orbit. 2.0 is the measured default. stats.transition_ribbon.world_len_p50_m reports what you actually got, and n_depth_capped how many columns the cap bit on.
ribbon_smudge_pxoptFLOAT120–200Blur the skirt ALONG the silhouette, in source-plate texels, reached at its outer edge and ramped in from the rim. Each column is frozen to a single texel, so at 0 the skirt is a fan of flat radial streaks that band against each other; this averages across neighbouring columns so the subject's own edge colour bleeds outward smoothly instead. Plate-relative like ribbon_px - a 7680px plate wants more than a 2K one. Applies in the viewport AND is baked into the exported GLB as vertex colour on a separate ribbon material, so a DCC shows the same softening. 0 = off (hard edge-extend).

Outputs (3)

NameTypeDescription
solveATLAS_SOLVEβ€”
hole_maskMASKβ€”
reportSTRINGβ€”