◎ Radiance HDR Exposure Blend
Merge exposures into one HDR frame
- low_exposure
- high_exposure
- mid_exposure
- blended_hdr
- blend_mask
- blend_info
Photographers solve the "too much dynamic range" problem by shooting three copies of the same frame at different exposures and merging them. HDRExposureBlend is that merge, turned into a ComfyUI node: it takes a dark exposure (good highlights), a bright exposure (good shadows), optionally a middle one, and fuses them into a single HDR image that keeps the best of each.
In ComfyUI terms, the realistic source is a generation run at multiple exposure offsets - say the same seed at −2 EV, 0 EV, and +2 EV - or a batch where you varied the exposure. The node's whole philosophy is in its description: "Takes highlights from low exposure and shadows from high exposure for optimal color grading."
How it works
The default Mertens Fusion is the classic exposure-fusion algorithm, and the source implements it properly: for each exposure it computes a weight map from contrast (Laplacian energy), saturation, and well-exposedness, then blends with those weights. No tone-mapping step is needed - the fusion is the merge. The other methods (Luminance Weighted, Shadow/Highlight Mask, Exposure Weighted, Laplacian Pyramid) are alternative weighting strategies; Mertens is the one to start with, Laplacian Pyramid the one to try when you see halos.
Before fusion, the exposures are normalized to the same scale using exposure_offset_low/high/mid - these tell the node the EV of each input relative to 0 so it can compensate. Defaults are −2/+2/0, which matches exposures you bracketed symmetrically.
The inputs
- low_exposure (dark) and high_exposure (bright) - required. mid_exposure optional.
- blend_method - the five-way choice above.
- shadow_weight / highlight_weight (0–2) - bias the merge toward shadows or highlights.
- transition_smoothness - feathering between exposure regions.
- exposure_offset_low / high / mid - the EV of each input; get these right or the merge fights itself.
- ghost_removal (default off) - for when the frames aren't perfectly aligned (motion between shots).
Outputs: blended_hdr (the merged float image), blend_mask (the weight map - great for debugging where each exposure won), and blend_info (a STRING summary).
The traps
- This wants exposures of the same frame. If your "bracketed" images are actually different generations, ghosting and motion artifacts are guaranteed - that's what ghost_removal exists for, but it only does so much.
- Mertens fusion expects roughly aligned, normal-range inputs. Feeding it wild float HDR data before normalizing will make the well-exposedness term meaningless.
- The output is a single merged HDR float image. From there it's the usual route: grade in linear, tone-map to SDR, or save as EXR. The pack's community framing - HDR/EXR work inside ComfyUI - is exactly the workflow this node serves.
Install
ComfyUI Manager → search Radiance, or:
cd ComfyUI/custom_nodes
git clone https://github.com/fxtdstudios/radiance.git
cd radiance
pip install -r requirements.txt
Restart. Under FXTD Studios/Radiance/Color.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| low_exposure | IMAGE | — | |
| high_exposure | IMAGE | — | |
| blend_method | COMBO | Mertens Fusion | 5 options: Mertens Fusion, Luminance Weighted, Shadow/Highlight Mask, Exposure Weighted, Laplacian Pyramid |
| mid_exposureopt | IMAGE | — | |
| shadow_weightopt | FLOAT | 1.00–2 | — |
| highlight_weightopt | FLOAT | 1.00–2 | — |
| transition_smoothnessopt | FLOAT | 0.300.05–1 | — |
| exposure_offset_lowopt | FLOAT | -2.0-6–0 | — |
| exposure_offset_highopt | FLOAT | 2.00–6 | — |
| exposure_offset_midopt | FLOAT | 0.0-6–6 | EV of the optional middle exposure relative to 0 EV. Applied as compensation so all three exposures are normalised to the same scale before fusion. |
| ghost_removalopt | BOOLEAN | false | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| blended_hdr | IMAGE | — |
| blend_mask | IMAGE | — |
| blend_info | STRING | — |