Nodes/radiance/OCIO ColorSpace
ComfyUI Node

OCIO ColorSpace

Getting ComfyUI out of sRGB jail

By FXTD-Studios·Created 8 months ago·Updated about 18 hours ago· 246
OCIO ColorSpace
  • image
  • image
  • grade_info
◄src_spaceLinear sRGB (D65)►
◄dst_spaceACEScg►
◄directionForward►
◄strength1.00►
◄grade_info_in—►

Every ComfyUI tensor you've ever seen is an sRGB-encoded 0–1 image pretending to be data. That's fine until you hand it to anything colour-managed: send an sRGB PNG into a Nuke comp or a Resolve timeline configured for ACES and the gamma-encoded values get treated as linear light, which blows out every merge and blend downstream. One un-managed decode poisons the comp. This node is the translator.

What it is

A colour space converter with sixteen spaces in the dropdown, split into three families: linear working spaces (Linear sRGB, ACEScg, ACEScc, ACEScct), display spaces (sRGB, Rec.709 OETF, Rec.709/BT.1886), and camera logs (LogC3, LogC4, F-Log2, C-Log3, Log3G10, DaVinci Intermediate, BMD Film Gen5, V-Log, N-Log).

You set src_space (what the pixels are now), dst_space (what you want), and it runs the conversion. direction flips it - Inverse swaps the two, which is handy when you've built a log-to-linear chain and want the same node to do the trip back.

How it works, and the one caveat

Everything routes through a Rec.709-primaries linear intermediate. When a config is loaded - Radiance auto-activates an ACES studio config at startup, and honours your $OCIO environment variable if you have one - the non-log spaces go through OpenColorIO proper. The camera logs are treated as transfer curves only: they decode the log curve and keep Rec.709 primaries, so LogC3 in is linear Rec.709 out, not linear ARRI Wide Gamut. The ACES choices are the exception, because those also convert AP1 primaries.

That's a legitimate design decision and it's documented in the tooltip, but it's the thing people get wrong. If you need a real gamut conversion from a camera space, do the log decode here and then the primaries conversion somewhere that knows about it - Radiance's own ARRI Wide Gamut node or an OCIO transform.

The other caveat is strength. It lerps between the input and the converted output on the raw values of two different encodings, so 0.5 is not "half the conversion" in any physical sense - it's a blend of sRGB numbers and linear numbers. Perfectly usable as an aesthetic dial, meaningless as a science dial. Leave it at 1 unless you're deliberately doing something weird.

Two outputs: image, and a grade_info STRING that records the chain. The optional grade_info_in input just gets tucked into that JSON as upstream - it does not change a single pixel.

Install

Radiance comes from ComfyUI Manager (search Radiance) or the usual clone:

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

opencolorio is in that requirements file, and the installer script also checks for it. If you're on Windows portable, use python_embeded\python.exe for the pip line. Restart and refresh.

Where people get burned

Install the deps into ComfyUI's Python, not your system one. This is the single most common Radiance support question and it produces a confusing error: the pack loads, the node appears, and one operation quietly does less than it should. Check the console at startup - Radiance logs whether PyOpenColorIO is available and which config it loaded.

That check matters here more than anywhere else in the pack. On an older Radiance release, ten of the sixteen advertised spaces had no analytic implementation at all and would silently return your input unchanged whenever OCIO wasn't configured. That's fixed - unsupported spaces now raise instead of passing pixels through - but if you're running a version from before 3.5 and your "conversion" looks identical to the input, this is why.

Then there's the conceptual trap: converting once, in the wrong place. If your pipeline is Read → convert → generate → Write, the write node needs to know what it's holding, and the VAE saw whatever you fed it. Decide your working space before you connect anything, and stick to it for the whole graph.

CategoryFXTD STUDIOS/Radiance/Color

Inputs (6)

NameTypeDefaultDescription
imageIMAGEImage encoded in src_space (or in dst_space when direction is Inverse).
src_spaceCOMBOLinear sRGB (D65)Encoding of the input. Camera-log choices decode the log curve only and keep Rec.709 primaries; ACES choices also convert AP1 primaries.
dst_spaceCOMBOACEScgEncoding to convert to. Camera-log choices apply the log curve only, on Rec.709 primaries.
directionCOMBOForwardForward converts src_space to dst_space. Inverse swaps them (dst_space to src_space).
strengthFLOAT1.000–1Mix between input and converted pixel values (0 = input, 1 = full conversion). The mix is done on the raw values of two different encodings.
grade_info_inoptSTRINGOptional grade_info JSON from an upstream node. Only recorded as "upstream" in this node's info output; it does not change the image.

Outputs (2)

NameTypeDescription
imageIMAGE—
grade_infoSTRING—