Nodes/radiance/Clip Detector
ComfyUI Node

Clip Detector

Find the highlights your SDR image already threw away

By FXTD-Studios·Created 8 months ago·Updated about 18 hours ago· 246
Clip Detector
  • image
  • clip_mask
  • clip_fraction
  • visualization
◄threshold0.970►
◄channel_modeany►
◄soft_edge0.030►
◄dilate_px8►

Here is the annoying truth about SDR-to-HDR: the data you want isn't in the file. A sky that reads 1.0, 1.0, 1.0 is not a bright sky, it's a dead pixel - the sensor or the export clipped it and no amount of careful grading brings it back. Radiance's whole SDR → HDR pipeline works by having a diffusion model invent plausible highlight detail, and inventing it everywhere is slow and ugly. Clip Detector's job is to tell the model where to look.

What it actually does

It's a mask generator. Feed it a display-encoded SDR image, it walks the pixels, and anything brighter than your threshold is flagged as clipped. That mask drives two other Radiance nodes: SDR → HDR Prepare uses it to build the inpainting region, and HDR Highlight Composite uses it to decide which pixels come back from the model and which stay pixel-perfect from the original.

The node also hands you a clip_fraction - the percentage of the frame that's blown. That number is the honest answer to "is this shot worth uplifting at all?" A sun-flared skyline might be 8% clipped. A properly exposed interior is 0.01%. If your clip fraction is zero, skip the reconstruction and save yourself the sampler time.

Three outputs:

  • clip_mask (MASK) - 1 where clipped, 0 where safe, soft-edged in between. This is the one you wire.
  • clip_fraction (FLOAT) - a QC number, useful in a ShowText or a conditional.
  • visualization (IMAGE) - the mask drawn over the image so you can eyeball whether it's catching what you think it's catching.

The controls that matter

Five inputs, and honestly you'll touch two of them.

threshold defaults to 0.97, which is deliberate - catching 1.0 exactly misses the near-white pixels that are just as unrecoverable. Drop it to 0.94–0.95 for footage with a gentle shoulder; you'd be surprised how much "slightly overexposed" footage is silently clipped.

channel_mode decides what counts as clipped:

  • any - a pixel is clipped if any RGB channel is over threshold. Most sensitive. This is the default and the right choice for a bright red taillight or a magenta neon sign.
  • all - only if all three channels are over. Tighter, fewer false positives, better for skin and practicals where you don't want to reconstruct every saturate.
  • luma - Rec.709 luminance over threshold. Middle ground, and the mode the soft edge follows too.

Then soft_edge (0.03) feathers the boundary below the threshold and dilate_px (8) grows the mask outward to cover the fringing that surrounds a blown highlight. Set dilate_px to 0 and you'll get hard-edged reconstruction seams; leave it at 8 and the model gets a comfortable margin. If your mask is creeping into areas you want untouched, that's the number to lower.

Install

It ships in Radiance, alongside ~147 other nodes. In ComfyUI Manager search Radiance and install, or from a terminal:

cd ComfyUI/custom_nodes
git clone https://github.com/fxtd-studios/radiance.git
cd radiance
python -m pip install -r requirements.txt

Restart ComfyUI and refresh the browser. Windows portable users should run that pip step with python_embeded\python.exe, or you'll install into the wrong Python and wonder why nothing imports. Nothing downloads for this node specifically.

Where people get burned

The big one is conceptual, not technical: this node finds missing data, it doesn't create it. If a third of your frame is clipped, you get a third of your frame invented, and the model's guess about what was in that window is exactly that - a guess. It's excellent on skies, practical lights and speculars; it will happily hallucinate nonsense in a clipped face.

Second, it expects display-encoded input, tested as-is with no decoding. Feed it scene-linear values above 1.0 and every pixel is "clipped" and your mask is a solid white rectangle. Linearise downstream, after the detector.

Third, the small stuff: if you just installed Radiance and the node is missing from the menu, restart ComfyUI and hard-refresh the browser - new node registrations don't always show up in a stale tab. And if you're upgrading from a pre-3.5 install, back up your workflows; some widget layouts changed in that release, and old graphs can come back with a mismatched input count.

CategoryFXTD STUDIOS/Radiance/HDR

Inputs (5)

NameTypeDefaultDescription
imageIMAGEDisplay-encoded SDR image (code values 0-1). Tested as is, no decoding.
thresholdFLOAT0.9700.5–1Pixels brighter than this are marked as clipped.
channel_modeCOMBOanyany: flag a pixel when any RGB channel is over threshold. all: only when all three are. luma: Rec.709 luma. The selected mode also controls the soft edge.
soft_edgeFLOAT0.0300–0.2Feathering width below the threshold. 0 = hard binary mask.
dilate_pxINT80–64Expand the clip mask outward to cover highlight fringing.

Outputs (3)

NameTypeDescription
clip_maskMASK—
clip_fractionFLOAT—
visualizationIMAGE—