Nodes/Radiance/Highlight Synthesis
ComfyUI Node

Highlight Synthesis

Radiance Highlight Synthesis — fake the roll-off that flat white skies deserve

By FXTD-Studios·Created 9 months ago·Updated 3 days ago· 249
Highlight Synthesis
  • image
  • image
◄threshold0.95►
◄expansion1.5►
◄detail_amount0.20►
◄detail_scale1.0►
◄blend_modeScreen►
◄seed0►

Nothing screams "AI image" faster than a clipped, featureless white sky. Real film and camera footage roll off softly into highlights - the brightest areas still carry texture, grain, a hint of structure. Diffusion models hit pure white and stop, because there's nothing in the training distribution past it. Radiance Highlight Synthesis is the fix: it takes the blown-out regions above a threshold and synthesizes plausible detail into them, the way a film scan retains texture where an 8-bit JPEG just clips.

The node is upfront about what it does, and the source docstring is honest about the word for it: it "hallucinates" detail in blown-out areas. This is not recovery - the pack's own README is explicit that it can't recover detail that was already clipped. It's synthesis: inventing grain and structure that reads as natural roll-off instead of flat white. For the "AI look" problem specifically, this is one of the cheapest single moves you can make.

How it works

Three stages, per the source: expand the dynamic range with a roll-off curve so values above the threshold push past 1.0; generate synthetic grain/texture tuned to the image's own statistics; then blend that detail into the expanded highlights so the result behaves like film clipping rather than a hard cut. The blend_mode - Screen, Add, or Soft Light - controls how the synthetic texture interacts with the base. Screen is the gentle default; Add is punchier; Soft Light is subtlest.

The seed input matters because the grain is generated, not computed. Same settings, different seed, different texture - which is exactly what you want when iterating on a shot, and exactly what you don't want if you're trying to match grain across a sequence. Lock the seed for consistency.

The inputs that matter

  • threshold - the luminance level above which synthesis kicks in. Default 0.95 means "only the top of the range"; drop it to 0.5 to treat everything brighter than mid-gray as a highlight.
  • expansion - how far to push values above 1.0. 1.5 default is a gentle extension; 4.0 is a dramatic HDR push.
  • detail_amount - strength of the synthetic grain in the highlights. 0.2 is subtle; past ~0.6 it starts to read as noise.
  • detail_scale - the frequency of the texture. Low = fine grain, high = soft clouds of detail.
  • blend_mode and seed - the flavor and the reproducibility knob.

Output: a single image.

Why you'd reach for it

Two situations, both common. The everyday one: a generation with a blown sky or a hot light source that looks dead. Run it through with defaults and the top of the frame gets back its texture. The pipeline one: you're doing HDR-style work and need values past 1.0 in the highlights - expansion pushes the range out so downstream tone mapping or EXR output has something to work with. The community's read on this pack is that it "won't create real 16/32-bit EXR" unless your input has the data - this node is precisely the tool that creates plausible data where the source has none, but keep expectations honest: it's simulated detail, not recovered signal.

Installing

cd ComfyUI/custom_nodes
git clone https://github.com/fxtdstudios/radiance.git
cd radiance
pip install -r requirements.txt   # or requirements_windows.txt / requirements_linux.txt / requirements_mac_silicon.txt

Or search Radiance in ComfyUI Manager, restart. Linux needs libopenexr-dev first.

Gotchas

The tuning trap is over-expansion: push expansion too far and your "film roll-off" turns into an obvious gray fog in the highlights, because you've stretched noise into brightness. Work from the defaults, judge at 100% zoom, and only then raise detail_amount. Second, if your image has no clipped highlights - nothing above threshold - the node does almost nothing, which reads as "broken." Check your histogram first. Third, remember it's seeded: for a sequence, lock seed or your grain will crawl between frames.

CategoryFXTD STUDIOS/Radiance/HDR

Inputs (7)

NameTypeDefaultDescription
imageIMAGEImage with clipped highlights, in any encoding (threshold is compared with its Rec.709 luma). Every channel, alpha included if present, receives the detail noise.
thresholdFLOAT0.950.5–1Luminance level above which to synthesize detail.
expansionFLOAT1.51–4Highlight gain above the threshold: gain = 1 + (luma - threshold) x (expansion - 1) x 2, faded in by the highlight mask. 1.0 = no expansion.
detail_amountFLOAT0.200–1Strength of synthetic grain in highlights.
detail_scaleFLOAT1.00.1–5Scale/frequency of the synthetic detail.
blend_modeCOMBOScreenHow the monochrome detail noise is combined. Add: plain offset. Screen: a + n - a x n, which inverts the noise on values above 1.0. Soft Light: contrast-style blend, normalised by the frame peak.
seedINT00–18446744073709550000Random seed for the detail noise; frame N of a batch uses seed + N. The same seed always gives the same pattern.

Outputs (1)

NameTypeDescription
imageIMAGE—