Nodes/radiance/HDR Color Convert
ComfyUI Node

HDR Color Convert

The primaries swap you'll use twenty times a day

By FXTD-Studios·Created 8 months ago·Updated about 18 hours ago· 246
HDR Color Convert
  • image
  • image
◄source_spacesRGB►
◄target_spaceACEScg►
◄exposure0.00►
◄gamma_adjust1.00►
◄chromatic_adaptationBradford►
◄use_gputrue►

There are two kinds of colour conversion nodes in this ecosystem. One is a full OpenColorIO transform with a config behind it, and one is a matrix multiply you can run in your sleep. HDR Color Convert is squarely the second. It ships precomputed industry-standard matrices, runs them on GPU, and gets out of the way. For "this is ACEScg, I need Rec.2020," it's faster to wire than any OCIO setup, and for most graphs it's the right call.

Reach for it when you're moving between primaries - sRGB, Rec.709, Rec.2020, ACEScg, ACES2065-1, ACEScct, DCI-P3, Display P3, DaVinci Wide Gamut, ARRI Wide Gamut 4, S-Gamut3.Cine. Reach for the pack's OCIO Transform node instead when you need a genuine camera-log decode or a look from a real config.

How it works

Conversion is a 3×3 primaries matrix plus a transfer-curve step on each end. The tooltip spells out the rule clearly and it's worth reading twice: sRGB and Rec709 are decoded with the sRGB curve, ACEScct with its log curve - everything else is treated as linear with those primaries. So Rec2020, DCI-P3, DaVinci Wide Gamut etc. are being treated as linear containers, not encoded ones.

The matrices are precomputed fast paths (including the D60↔D65 adaptation already folded in), which is why this thing is cheap and why one of its inputs is quietly a no-op - more on that below. The node's own changelog notes a v2.1 fix where DaVinci Wide Gamut primaries had been a copy-paste of DCI-P3; if you're on an ancient build and getting slightly wrong reds, that's why.

Inputs and outputs

Required: image, source_space, target_space - the same twelve-entry list on both ends. Getting the pair right is 90% of using the node.

Optional: exposure (stops), gamma_adjust (1.0 = no change), use_gpu (CUDA/MPS, falls back to CPU automatically), and chromatic_adaptation.

That last one deserves an honest callout, because the author already made it in the tooltip: the D60↔D65 adaptation is already baked into the precomputed matrices using Bradford, so changing chromatic_adaptation does not currently alter the output. Pick Von Kries and you get a warning log and the same pixels. It exists for workflow compatibility. Don't build a roundtrip test around it and then wonder why the numbers don't move.

One output: image.

Install

ComfyUI Manager → search Radiance → Install → restart ComfyUI → refresh your browser. Manual route:

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

Windows portable users need python_embeded\python.exe for the pip step. This node needs no model files, but note the pack as a whole installs OpenColorIO, OpenImageIO, OpenEXR (Python <3.14 only, since no wheel exists beyond that), diffusers and accelerate - installing Radiance for one matrix node still means carrying all of it.

Where people get burned

The "everything else is linear" rule bites people who assume the name implies an encoding. ARRI Wide Gamut 4 here means the primaries, treated as linear. If you hand it a real LogC4 file and ask for sRGB, you'll get a plausible-looking, wrong result - the log curve was never removed, so you've linearised nothing. That's an OCIO job.

Second: chaining conversions is lossy in a way you can't see per step but can see in a roundtrip. Convert ACEScg → Rec.709 → ACEScg a few times and your saturated colours will have crept. Do the conversion once, in the right place, rather than sprinkling converts along the chain because a preview looked off.

Third - and this is the general Radiance gotcha worth internalising - grading and conversion nodes in this pack operate on a tensor, not a file, so nothing is re-clamped for you. Values above 1.0 stay above 1.0, and a downstream node that assumes 0–1 will quietly crush them.

CategoryFXTD STUDIOS/Radiance/Color

Inputs (7)

NameTypeDefaultDescription
imageIMAGEImage encoded as source_space.
source_spaceCOMBOsRGBEncoding of the input. sRGB and Rec709 are decoded with the sRGB curve and ACEScct with its log curve; every other option is treated as linear with those primaries.
target_spaceCOMBOACEScgEncoding of the output. sRGB and Rec709 get the sRGB curve and ACEScct its log curve; every other option is written linear with those primaries.
exposureoptFLOAT0.00-10–10Exposure adjustment in stops (EV)
gamma_adjustoptFLOAT1.000.1–5Gamma adjustment (1.0 = no change)
chromatic_adaptationoptCOMBOBradfordChromatic adaptation method. NOTE: the D60<->D65 adaptation is already baked into the precomputed FAST_MATRICES this node converts with (Bradford), so changing this does not currently alter the output. Kept for workflow compatibility; selecting a non-Bradford method logs a warning.
use_gpuoptBOOLEANtrueRun the effect on GPU via CUDA/MPS. Falls back to CPU if unavailable.

Outputs (1)

NameTypeDescription
imageIMAGE—