Metalness Map
Turning a flat render into a PBR material — with the honest caveat
- image
- source_mask
- mask
- image
- mask
- metalness_info
People keep asking how to get a metalness map out of an AI image. There's a running thread on r/StableDiffusion of exactly this: someone has their normal map sorted and wants "the rest like roughness, metalness, AO" and can't find nodes for it. x1MetalnessMap is one of the better answers - a one-shot node that derives a grayscale metalness map straight from your image, no scanning hardware, no external model.
It's part of MKRShift Nodes' Surface/Maps family, which is the pack's real strength: a full set of material-map derivation nodes that share one consistent vocabulary. Feed any of them an image and they emit a grayscale scalar map plus a mask, so the maps you build all play nicely together when you hit the pack step.
How it works, honestly
The default source_mode is combined_metalness, and the author is upfront about what that means: it's an artist-driven lookdev solve, not a physically measured metalness map. The algorithm mixes a few heuristics - it biases toward bright, chrome-like or colored-metal-like regions, pulls in local surface detail, and weights by luminance - then normalizes the result. In practice that's exactly what you want for game-asset or preview work: a believable starting point you can art-direct, not a scientific measurement.
Everything else follows the family's shared normalization vocabulary:
normalize_mode-auto_percentile(default, robust to outliers),manual_range, orauto_rangepercentile_low/percentile_high- the percentile range when auto-percentile is on (default 2–98, which throws away the darkest/brightest 2% so noise doesn't stretch your map)gamma,contrast,blur_radius- shape and soften the resultdetail_radius/detail_strength- how much fine surface detail gets weighted into the solveinvert_values- flip metallic ↔ non-metallic
All of these live in a single settings_json string rather than dedicated widgets. It's the pack's house style: more power, less discoverability. The defaults are sane, so you can honestly leave the JSON alone on a first run.
Inputs and outputs
Required: image and settings_json. Optional: source_mask (used when you set source_mode to mask, or to constrain the solve) and mask (limits where the metalness map is emitted - outside it you get a flat neutral). Outputs:
image- the grayscale metalness map (IMAGE)mask- the normalized scalar as aMASKmetalness_info- aSTRINGsummary of resolved settings and the actual normalization range it used
That info string is worth a look: it tells you the real percentile range, which saves you guessing why a dark scene produced a washed-out map.
What to wire it into
The obvious destination is x1PBRPack (also in this pack) or the metalness slot on x1PreviewMaterial's shader ball. A practical pipeline is x1RoughnessMap + x1MetalnessMap + x1NormalMap → x1PBRPack → an ORM texture. Higher output values = more metallic response, which is how your renderer will read it.
Installing it
Search "MKRShift Nodes" in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Restart and you're set. No requirements.txt, no model downloads, no ffmpeg needed - pure numpy math on the image tensor. The only real cost is repo size: the pack ships a lot of unrelated machinery (host bridges, G-code, audio), so you're pulling in a big install for one family of nodes. If you only want material maps, this is still the cleanest bundle that keeps them all on the same normalization language.
Where people trip
Expecting physical accuracy. combined_metalness guesses; it will call a glossy dark plastic "metallic" sometimes. If that matters, set source_mode to a channel or luma and feed the map yourself. Also watch contrast - the default 1.15 pushes mid-grays toward full metal or full dielectric fast, so if your map looks binary, drop it back toward 1.0 and let detail_strength do the work.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| settings_json | STRING | {"source_mode":"combined_metalness","normalize_mode":"auto_percentile","value_min":0.0,"value_max":1.0,"percentile_low":2.0,"percentile_high":98.0,"detail_radius":2.0,"detail_strength":0.25,"gamma":1.0,"contrast":1.15,"blur_radius":0.0,"invert_values":false,"mask_feather":8.0,"invert_mask":false} | — |
| source_maskopt | MASK | — | |
| maskopt | MASK | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| metalness_info | STRING | — |