Nodes/radiance/◎ Radiance HDR Shadow/Highlight Recovery
ComfyUI Node

◎ Radiance HDR Shadow/Highlight Recovery

Pulling detail out of the shadows and highlights — without clipping anything

By fxtdstudios·Created 7 months ago·Updated 9 days ago· 242
◎ Radiance HDR Shadow/Highlight Recovery
  • image
  • recovered_image
shadow_amount0.50
highlight_amount0.50
shadow_tone0.25
highlight_tone0.75
color_correction0.5
local_contrast0.0

Every image you've ever graded has the same tension: lift the shadows and the blacks turn gray and muddy; pull the highlights down and the whites go flat. HDRShadowHighlightRecovery is the Radiance node that does both at once, on a single image, in float32, with separate control over where the shadow and highlight zones sit.

The trick it pulls off is worth understanding because it's why this isn't just a contrast slider in a costume. It computes luminance, then builds masks: shadows get an exponential-decay mask (full at black, falling to zero by the shadow_tone point), highlights get a sigmoid-style mask that stays at zero until the highlight_tone and keeps rising above 1.0 - so it works on super-whites too, not just "pixels between 0.5 and 1.0." Shadows get boosted by the shadow_amount, highlights get softly compressed by the reciprocal of the highlight amount. Because it's all masks over a float image, nothing gets hard-clipped; the detail that was there comes back and the values that were above 1.0 stay above 1.0.

The inputs

  • shadow_amount / highlight_amount (0–2, default 0.5 each) - how hard to recover each end. Start at 0.5, nudge up.
  • shadow_tone (0–0.5, default 0.25) - where the shadow zone ends. Lower = only the deepest shadows get lifted.
  • highlight_tone (0.5–1, default 0.75) - where highlight compression begins. Lower it to start taming highlights earlier.
  • color_correction (0–1, default 0.5) - the subtle but important one: lifted shadows desaturate fast, so this pulls saturation back toward the luminance to keep shadows from going purple/green.
  • local_contrast (−1 to 1, default 0) - a Gaussian-based local contrast pass (GPU-accelerated when available, scipy fallback otherwise) for adding midtone pop after recovery.

Output: recovered_image, float32.

Where it fits

This is a recovery, not a hallucination. The source masks work on detail that exists in the data - lifting shadows reveals what's already recorded there. If your shadow detail was crushed to pure black in an 8-bit export, there's nothing to reveal, and the README's standing warning applies: no Radiance node can recover detail that was clipped upstream. Where this shines is the typical AI-generation case: the model produced a float image with a wide tonal range, and the shadows are technically there but sitting below your display's ability to show them.

Pipeline-wise: run it after you're in linear (or right on the VAE output), then tone-map to finish. It pairs naturally with HDRExpandDynamicRange - expand for headroom, then recover the ends - though for most people this single node is the whole fix.

Install

Part of Radiance - 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.

CategoryFXTD Studios/Radiance/Color

Inputs (7)

NameTypeDefaultDescription
imageIMAGE
shadow_amountFLOAT0.500–2
highlight_amountFLOAT0.500–2
shadow_toneoptFLOAT0.250–0.5
highlight_toneoptFLOAT0.750.5–1
color_correctionoptFLOAT0.50–1
local_contrastoptFLOAT0.0-1–1

Outputs (1)

NameTypeDescription
recovered_imageIMAGE