Roughness Map
The hard part of PBR from an image, solved by a default
- image
- source_mask
- mask
- image
- mask
- roughness_info
Roughness is the PBR map people underestimate. Metalness is binary-ish, normals are mechanical, but roughness is where materials actually read as real - the difference between a mirror and a matte plastic lives entirely in that one grayscale map. And it's the hardest one to fake from a flat image, because roughness isn't in any single channel; it's in the interplay of highlights, micro-detail, and saturation. x1RoughnessMap from MKRShift Nodes is built to handle exactly that interplay.
It's part of the pack's Surface/Maps family, and the author's honest framing is the right one: combined_roughness is a practical lookdev default, not a physically measured solve. It mixes luminance, fine surface detail, and saturation into one scalar, normalizes it, and hands you a map your renderer will read correctly.
How the default solve works
With source_mode set to combined_roughness (the default), the node blends three signals - luminance, isolated fine detail, and saturation - weighted toward what reads as roughness on a real surface. Higher output values = rougher, less mirror-like. The blend weights are in the source: roughly half luma, a strong detail term (boosted by detail_strength), and a smaller saturation contribution. It's a heuristic, but it's a well-chosen one for the "turn a render into a material" job.
The rest is the family's shared vocabulary:
normalize_mode-auto_percentile(default),manual_range, orauto_rangepercentile_low/percentile_high(2–98) - throw away the noisy extremes so the map doesn't get stretched by specular spikesdetail_radius/detail_strength- how aggressively fine surface detail is pulled into the solve. This is the dial that brings out grain, pores, and weavegamma,contrast(1.1 default),blur_radius,invert_values- shape, smooth, and flip the result
All of it in a settings_json string, per the pack's house style. The defaults are genuinely good - contrast 1.1 gives the map presence without making it binary.
Inputs and outputs
Required: image and settings_json. Optional: source_mask (when source_mode is mask, or to constrain the solve) and mask (limits where the roughness map is emitted).
image- the grayscale roughness mapmask- the normalized scalar as a MASKroughness_info- summary string of the resolved settings and normalization range
Where it slots in
The canonical flow: x1RoughnessMap + x1MetalnessMap + x1NormalMap → preview on x1PreviewMaterial's shader ball → pack with x1PBRPack. This is the answer to the recurring community question - people literally ask "how do I get roughness/metalness/AO nodes" on r/StableDiffusion - and the pack's Surface branch is a coherent response to it. If your material looks "too clean," the first knob to turn is detail_strength, not the base model.
Installing it
ComfyUI Manager (search "MKRShift Nodes") or:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Restart, no requirements, no model downloads, no ffmpeg. Big repo, coherent small family - worth it if material work is a regular thing.
Where people get burned
The same trap as x1MetalnessMap: expecting measurement. combined_roughness will call a glossy surface "smooth" when the image gives it no highlight info to work with, and it guesses on dark scenes. If a region reads wrong, either feed it a better-lit source or switch source_mode to luma and drive the map yourself. And watch contrast: above ~1.4 the map collapses toward all-black/all-white, which is how you lose the midrange roughness that makes surfaces feel physical.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| settings_json | STRING | {"source_mode":"combined_roughness","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.45,"gamma":1.0,"contrast":1.1,"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 | — |
| roughness_info | STRING | — |