CoCo Colorspace
Why your EXR looks washed out, and the node that fixes it
- images
- IMAGE
Every 3D person hits this the first time they load a render pass into ComfyUI: the image looks flat, gray, and wrong. It's not broken. The EXR you rendered is scene-linear - raw light values - and ComfyUI displays images as if they were sRGB, which is a gamma-encoded space. Linear data shown without a conversion reads washed out and dark in the shadows. CoCo Colorspace is the pack's answer: pick the space your file is in, pick the space you need, and it converts.
How it works
It's a thin, honest wrapper around colour-science, which does the heavy lifting. The from_colorspace and to_colorspace dropdowns each offer 15 options, and the family should look familiar if you've ever touched ACES or video:
ACES2065-1, ACEScg, ACEScct, ACEScc, sRGB, sRGB Linear, Rec.709, Rec.709 Linear, Display P3, Display P3 Linear, Rec.2020, Rec.2020 Linear, Adobe RGB, Adobe RGB Linear, and Raw (a passthrough).
Mechanically it does the classic three-step: decode the source if it's gamma-encoded (sRGB/Rec.709/P3/2020 have their transfer curve removed), do a linear-to-linear matrix conversion between the two primaries via colour, then apply the target's encoding curve. In plain terms: it converts, it doesn't grade. There's no tone mapping, no exposure control, no creative look - this is a faithful space-to-space transform.
The two conversions that matter
You'll use this node for two moves 90% of the time:
- Linear → sRGB. Feed it a linear render pass, get a proper displayable image. This is the move in the pack's own example workflow: every render pass coming out of Load EXR gets a
Linear_to_sRGBColorspace node before it hits a preview or a diffusion model, because diffusion expects something sRGB-ish, not scene-linear floats. - sRGB → Linear. The reverse, when you want to composite in linear light or feed a ControlNet that expects linear data.
Keep from/to honest - set from to what the file actually is. If your EXR is linear and you tell it from: sRGB, you'll double-decode and get something too bright. When in doubt, Raw → sRGB on an unmodified EXR is a safe starting point that just applies the display curve.
Inputs and outputs
images(IMAGE) - batch-aware, works on sequences.from_colorspace/to_colorspace- the enums above.- Output: a single IMAGE.
Gotchas
The code leans on sRGB's transfer curve as a stand-in for several spaces - the source literally notes Rec.2020 "uses the same EOTF as sRGB for simplicity" - so for broadcast-precise Rec.2020 work this is a simplification, not a reference-grade conversion. Also, scene-linear values routinely sit above 1.0 and below 0.0, and the node only cleans NaN/Inf, it doesn't clip. A lot of downstream ComfyUI nodes will assume a [0,1] image, so if you're feeding a diffusion model you usually want the target to be sRGB (encoded) rather than a linear space.
Installing it
Part of the CoCoTools pack - Manager search "CoCoTools", or:
cd ComfyUI/custom_nodes
git clone https://github.com/Conor-Collins/ComfyUI-CoCoTools_IO
pip install -r ComfyUI-CoCoTools_IO/requirements.txt
The color science runs on colour-science, one of the pack's listed dependencies; if the node errors on import, that's the package that didn't install. It's the pack's most reusable node beyond the EXR stuff - it takes any IMAGE tensor, so you can even use it to fix a batch of normal screenshots you over-graded in another app. The 15-space list is broad enough that most people never need more, and at 7 lifetime impressions it's criminally under-discovered.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| from_colorspace | COMBO | 15 options: ACES2065-1, ACEScg, ACEScct, ACEScc, sRGB, sRGB Linear, +9 | |
| to_colorspace | COMBO | 15 options: ACES2065-1, ACEScg, ACEScct, ACEScc, sRGB, sRGB Linear, +9 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |