Histogram Matcher
Make one texture's values match another's — the consistency node
- source
- reference
- IMAGE
PBR maps are supposed to be consistent across a material set - and they rarely are, because each one was generated by a different process with a different range. One height map bottoms out at 0.3, the next at 0.6. Histogram Matcher fixes exactly that: it reshapes the value distribution of a source image to match a reference image's distribution, so two maps that should have the same range actually do.
It's the "align the maps" node you reach for when assembling a set of textures that need to behave identically in-engine - like normalizing a folder of height maps that came from different generators, or grading two albedos to the same brightness feel.
How it works
Classic histogram matching: the node computes the cumulative distribution of both images, then builds a value mapping that pushes the source's histogram onto the reference's. The three modes control what gets matched:
- Grayscale - flattens everything to luminance and matches that. The tooltip's pick for height maps.
- Luminance (Preserve Color) - matches brightness while keeping the source's colors. The pick for color grading.
- Per Channel (RGB) - matches R, G, and B independently. The pick for normal maps, where each channel encodes direction data and needs its own alignment.
Inputs and outputs
source- the image whose histogram gets reshaped.reference- the target distribution. Note the tooltip: only the first image in the batch is used, so a batch of sources can all be matched against one reference.mode- one of the three above (default Grayscale).
Output: a single IMAGE with the source's content but the reference's distribution.
Install
Ships in ComfyUI-Leputen-Utils:
cd ComfyUI/custom_nodes
git clone https://github.com/lilquail/ComfyUI-Leputen-Utils
Restart ComfyUI, find it under Leputen-Utils → Image. Pure numpy/tensor math, no heavy deps beyond the pack's own.
Troubleshooting
- Wrong mode for the job - Per Channel on an albedo shifts hue badly (each channel is stretched independently). Grayscale on a normal map destroys it. Match the mode to the map type and 90% of "this looks wrong" disappears.
- Colors look off in Luminance mode - that's expected; it's a brightness match, and it will alter perceived saturation. If you need exact color fidelity, this isn't a color-grading LUT - it's a distribution match.
- Reference from a batch surprise - feed a batch into
referenceand only the first image counts. Load a single reference if you want predictability. - Extreme source/reference mismatch - if the source has almost no range, the match can amplify noise. Clean or level the source first.
The honest use case: this node isn't exciting, but it's quietly one of the most useful things in the pack for batch pipelines. When your AO maps look different from each other just because they were generated differently, a histogram match against one "reference" map makes the whole set coherent in one pass.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| source | IMAGE | The image whose histogram will be matched to the reference. | |
| reference | IMAGE | The target histogram to match against. Only the first image in the batch is used. | |
| mode | COMBO | Grayscale | Grayscale: Output is grayscale. Luminance: Match brightness, preserve colors. Per Channel: Match R/G/B independently. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |