Add Normals
Layering normal maps without wrecking your lighting
- base_normal
- detail_normal
- IMAGE
If you've ever just added two normal maps together with a lerp node and then stared at a weirdly flat, double-lit surface in your game, this is the node you were missing. Add Normals blends a base normal map with a detail normal map using the actual blending algorithms that game engines use, so the result stays a valid normal map instead of a mess.
It's part of ComfyUI-Leputen-Utils, the game-dev texture toolkit (DDS loading, PBR map generation, DeepBump AI). If your workflow touches game textures at all, this pack is one of the few that treats normal maps as a first-class thing instead of an afterthought.
How it works
A normal map stores a surface direction per pixel. You can't just average two of them - you get a direction that's wrong for both. The four methods here are the standard approaches (the pack credits the classic "Blending in Detail" paper by Barré-Brisebois and Hill):
- UDN - adds the XY components, keeps the base's Z. Fast and cheap, fine for subtle overlays, goes flat on steep angles.
- Whiteout - the industry standard (Unity, Unreal). Multiplies the Z channels too, so it preserves volume in both maps. Best default for most work.
- Partial Derivatives - treats the normals as surface slopes and blends those. Accurate, but it can flatten things.
- Reoriented Normal Mapping (RNM) - mathematically the most correct; it rotates the detail map to follow the base map's surface. Slower, but the one to pick when you're layering steep detail and anything else looks wrong.
detail_strength (0–4, default 1) scales the detail map's contribution before blending - push it past 1 to exaggerate, down to 0 and you get the base map untouched.
Inputs and outputs
Four inputs, all in required:
base_normal- your primary map, typically the large-scale surface.detail_normal- the finer detail you're layering on.detail_strength- how hard the detail bites.method- the blend algorithm above (default UDN; bump it to Whiteout).
Output is a single IMAGE - one normal map ready to plug into a saver, a Normal Map Converter, or straight into your game pipeline.
Install
It ships in the Leputen-Utils pack. Easiest is ComfyUI Manager (search "ComfyUI-Leputen-Utils"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/lilquail/ComfyUI-Leputen-Utils
Then restart ComfyUI. First startup auto-installs the Python deps (scipy, opencv-python, onnxruntime, imageio) and clones DeepBump into vendor/. You'll find the node under Leputen-Utils → NormalMap.
Troubleshooting
The node is pure tensor math, so it's low-drama. Two gotchas that aren't its fault:
- Feed it actual normal maps. If you plug in a color/albedo image, you get garbage that looks "sort of" normal - normalize or convert first.
- DirectX vs OpenGL Y-flip. If your final map lights "inside out" in-engine, flip the Y with a Normal Map Converter node before or after blending - the blend doesn't care, but your engine does.
One opinion: for a beginner, leave it on Whiteout. It's the default choice in both Unity and Unreal for a reason, and UDN's flatness on steep geometry is exactly the artifact that sends people down a rabbit hole.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| base_normal | IMAGE | The primary normal map, typically representing larger surface details. | |
| detail_normal | IMAGE | The secondary normal map containing finer details to be layered onto the base normal map. | |
| detail_strength | FLOAT | 1.000–4 | Controls the intensity of the detail normal map's effect on the base normal map. |
| method | COMBO | UDN | UDN: Fast, good for overlays. Whiteout: Industry standard, preserves detail. Partial Derivatives: Mathematical blend. Reoriented: Most accurate, slowest. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |