Extract Displacement Map
Turn a normal map into a height field ComfyUI can warp with
- image
- displacement_map
You want to make a logo ride the bumps of a wrinkled shirt, a brick wall, or a leather mug. That's a height-field job, and ComfyUI doesn't hand you one for free. This node is the cheap, honest version of it: feed it a normal map, get back a single-channel displacement map you can warp other images with. It's the setup half of the pack's one trick - the payoff is its sibling DisplaceLogo.
What it actually does
Straight from the author's README: "This node accepts a Normal Map and outputs a Displacement Map." Full stop. The code behind it is short and does exactly two things: it converts the input to grayscale using standard luminance weights (0.2989*R + 0.5870*G + 0.1140*B), normalizes that to the 0–1 range, and multiplies by your intensity. That's the whole node.
Now the honesty part, because you deserve it: this is not a real normal-to-height reconstruction. Doing that properly means solving a Poisson equation over the gradients of the normal map - an afternoon of linear algebra, which is very much not what this does. It takes luminance and calls it height. For a typical tangent-space normal map (blue channel ≈ "up", red/green encoding slope) that's a rough-but-serviceable height field, because the relative variation that matters for warping survives the desaturation. It also happily grayscales anything you feed it, including a depth map or a plain photo. Nothing stops you; it just won't be geometrically accurate. For sticking a logo on something bumpy, you don't need accurate - you need bumps.
The inputs and outputs that matter
- image (IMAGE) - the normal map. Get one from a ControlNet normal preprocessor in
comfyui_controlnet_aux(Normal BAE, etc.) or from a texture's baked normal map. - intensity (FLOAT, default 1, range 0–10, step 0.1) - the only dial you'll touch. Scales the height field; crank it up for more dramatic warp in the next node.
- displacement_map (IMAGE) - the output. Wire it into the
displacement_mapinput of DisplaceLogo, or any other node that eats a height field.
Install
Tiny pack, no models, no keys, no heavy downloads. Its requirements.txt pins torch, torchvision, numpy, and Pillow - every one already installed in any working ComfyUI. Install through ComfyUI Manager by searching ComfyUI_DisplacementMapTools, or:
cd ComfyUI/custom_nodes
git clone https://github.com/risunobushi/ComfyUI_DisplacementMapTools
Restart ComfyUI and you're done.
Where people get burned
The README warns the displacement map "cannot currently be previewed, but it's there, trust me." True - the output is a single-channel tensor, so the normal preview/save nodes won't show it. To peek, run it through something that broadcasts to RGB (like an image convert node) or just skip straight to the DisplaceLogo result. Second gotcha: the node only processes the first frame of a batch (image[0]), so don't feed it a stack and expect a full sequence. And if your final warp looks flat, it's usually your input map, not this node - a mostly-uniform normal map gives a mostly-uniform height field, and no amount of intensity fixes that. The author's own framing - "do something easy that I needed ComfyUI to do and I couldn't find nodes that did" - is the right expectation: this is a personal utility, not a renderer, and it's great at the one thing it claims.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| intensity | FLOAT | 1.00–10 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| displacement_map | IMAGE | — |