Nodes/ComfyUI Body Decal/Body Decal Surface Warp
ComfyUI Node

Body Decal Surface Warp

Displacement and depth warping for decals

By verias·Created 3 months ago·Updated 3 months ago· 1
Body Decal Surface Warp
  • decal_layer
  • decal_mask
  • depth_map
  • displacement_map
  • region_mask
  • clip_mask
  • warped_decal_layer
  • warped_decal_mask
depth_strength_x0.0
depth_strength_y0.0
depth_neutral0.50
displace_strength_x0.0
displace_strength_y8.0
displace_neutral0.50

Body Decal Surface Warp is the "conform it to the surface" stage of the modular pipeline. A decal that's been perspective-warped still sits on the body; this node makes it follow the surface - muscle definition, clothing wrinkles, fabric folds, the contour of a limb - by pushing its pixels around with a displacement map and a depth map. It's the difference between a tattoo that looks painted on a mannequin and one that looks printed on skin.

You feed it the outputs of Body Decal Place (decal_layer, decal_mask), optionally add maps, and get back a warped layer and mask for Body Decal Composite. It's also a great place to understand what the all-in-one Body Decal Apply is doing internally - that node has the same depth_* and displace_* inputs folded in.

How it works

The mechanism is a reverse-mapped, bilinear-sampled warp: for each output pixel it reads the displacement map, computes offset = map_value − neutral, and samples the decal from a source position shifted by strength_x/strength_y times that offset. What that means in practice:

  • Neutral gray (depth_neutral/displace_neutral, default 0.5) means no shift. Areas of the map brighter than neutral push pixels one way, darker push the other. The strength_* values scale how far - and they can go negative to flip direction.
  • A map that's all 0.5 does nothing. A map at 0 or 1 is a constant-shift disaster. You want something with local variation - that's what the wrinkles and muscle ridges encode.

Depth is applied first, then displacement. The two are conceptually similar but sourced differently: depth_map typically comes from a depth preprocessor (Depth Anything, MiDaS - the KB's depth essay is the rundown on those) and captures scene-level contour; displacement_map is usually a texture-derived map, like the output of this pack's own Image To Displacement Map node, and captures surface detail.

Inputs

Required are decal_layer and decal_mask plus the strength/neutral pairs. The optional inputs are where the maps come in: depth_map, displacement_map, region_mask, and clip_mask. region_mask multiplies into the decal's alpha (so warping only visibly applies where the region was), and clip_mask does the same from the other direction - handy for keeping a decal off the edges of the body.

Outputs are warped_decal_layer and warped_decal_mask, ready for Body Decal Composite.

Gotchas

Here's the trap that catches everyone: the sliders have defaults of displace_strength_y = 8 and the rest at 0, but with no map fed in, the node is a no-op pass-through. Cranking the strength sliders does nothing unless a displacement_map or depth_map is actually wired in - the code bails out early when a map is missing. Also, displacement maps need a sane neutral value or the whole decal shifts sideways rather than conforming; 0.5 is right for the maps Image To Displacement Map produces, and if your decal visibly slides, check that displace_neutral matches the map's midpoint.

Install: ComfyUI Manager → "ComfyUI Body Decal", or git clone https://github.com/verias/comfyui-body-decal.git into ComfyUI/custom_nodes and restart. Deps are just numpy and Pillow; the depth maps come from preprocessor packs you'll already have for ControlNet work.

Categoryimage/postprocessing/body decal

Inputs (12)

NameTypeDefaultDescription
decal_layerIMAGE
decal_maskMASK
depth_strength_xFLOAT0.0-100–100
depth_strength_yFLOAT0.0-100–100
depth_neutralFLOAT0.500–1
displace_strength_xFLOAT0.0-100–100
displace_strength_yFLOAT8.0-100–100
displace_neutralFLOAT0.500–1
depth_mapoptIMAGE
displacement_mapoptIMAGE
region_maskoptMASK
clip_maskoptMASK

Outputs (2)

NameTypeDescription
warped_decal_layerIMAGE
warped_decal_maskMASK