Everyone doing visual work has had this happen. The piece looks right on your monitor. In the gallery, on the projector, it is washed out and slightly green. Or the grade that was perfect in the suite looks crushed on a laptop. Or two monitors side by side, same cable, same file, different image.
These are not calibration accidents. They are three specific, separable things being mismatched, and knowing which three makes the problem tractable.
A hex code is not a colour
Start here, because almost everything downstream follows from it.
#FF0000 does not mean “red.” It means “put the red channel at maximum.” What colour that produces depends entirely on what your display’s red actually is — the physical spectrum its red subpixel emits. A wide-gamut monitor’s full-intensity red is a visibly deeper, more saturated red than a standard monitor’s.
So an RGB triple is a set of instructions to a device, not a description of a colour. To turn instructions into a colour you need to know three things about the device:
Its primaries — the actual chromaticities of its red, green and blue. This defines the triangle of colours it can produce at all: its gamut.
Its transfer function — how a numeric value maps to emitted light intensity. Not linear, for good reasons, covered below.
Its white point — what the display calls white when all three channels are at maximum. D65 is the standard; cinema projection has historically used something warmer.
A colour space is exactly those three pieces of information, and nothing more mysterious than that. sRGB, Display P3, Rec. 709, Rec. 2020, DCI-P3 — each is a specific choice of primaries, transfer function and white point.
The transfer function, and why it isn’t a mistake
The most common misunderstanding in this area is that “gamma” is a legacy quirk from CRTs that we are stuck with. It is not. It is doing something useful.
Human brightness perception is roughly logarithmic. We can distinguish very small differences between dark tones and are comparatively insensitive to differences between bright ones. If you encode light linearly in 8 bits, you spend most of your 256 values on bright steps nobody can tell apart, and you run out of values in the shadows — which is exactly where banding appears.
A non-linear transfer function spends the available bits where the eye can see them. Gamma encoding is perceptual compression, and it is the reason 8-bit images look acceptable at all.
Two terms worth getting right because they are constantly confused:
OETF — opto-electronic transfer function. Scene light in, code value out. What a camera does.
EOTF — electro-optical transfer function. Code value in, emitted light out. What a display does.
They are not inverses of each other, and the gap between them is deliberate: it accounts for the fact that you are viewing a bright image in a dim room, which changes apparent contrast. That intentional mismatch is called the OOTF, and it is why a film graded for a dark cinema looks flat in daylight.
The sRGB transfer function is also not simply “gamma 2.2.” It is a piecewise function — a short linear segment near black, then a power curve with an exponent of 2.4 — which together approximate 2.2 overall. The linear toe exists to avoid an infinite derivative at zero. Treating sRGB as pure 2.2 introduces small errors in the shadows, which is where you least want them.
Gamut mapping has no correct answer
Here is the part that is genuinely unsolvable rather than merely fiddly.
If your image contains a colour your display cannot produce — a saturated cyan in Display P3 shown on an sRGB monitor — something has to give. The options are all compromises:
Clip. Move the colour to the nearest point on the gamut boundary. Preserves everything in range exactly, and destroys all distinction between out-of-range colours — a gradient of increasingly saturated reds becomes a flat patch. This is what happens by default when nobody thinks about it.
Compress. Scale the whole image’s saturation inward so everything fits. Nothing clips, and every colour in the image changes, including the ones that were fine.
Perceptual intent. Compress non-uniformly, preserving relationships between colours more than absolute values, on the theory that the eye notices wrong relationships more than wrong colours.
There is no right choice. There is a choice appropriate to the image and the use, which is why colour management has “rendering intents” rather than an algorithm. A piece with a flat field of saturated colour wants different handling from a photograph, and no automatic system knows which it has.
What ACES is actually for
ACES — the Academy Colour Encoding System — gets described as “a colour space,” which undersells it. It is a pipeline architecture, and the idea is simple once stated.
Rather than converting between every pair of devices, you convert into a single very large working space, do all your work there, then convert out to whichever display you are targeting.
- An IDT (input transform) brings each camera’s native encoding into ACES
- Work happens in ACES, whose primaries are deliberately larger than any real display’s — it can represent colours no device can show, which sounds useless and is the point: nothing gets clipped mid-pipeline
- An ODT (output transform) maps ACES to a specific display
The win is combinatorial. With n cameras and m displays, direct conversion needs n×m transforms, each a place to get it wrong. ACES needs n + m. And critically, the decisions about how to handle out-of-gamut colour live in one place — the ODT — instead of being distributed through the project.
The cost is that ACES’s output transform imposes a look. It is a well-considered film-like tone curve, and it is not neutral, which is why some people fight it.
So: the projector
Back to the gallery. The image looked right on your monitor and wrong projected. The likely culprits, in order:
Different primaries. Projectors, especially laser projectors, have very different gamuts from monitors — frequently wider in green, narrower in red. Saturated colours shift.
No transfer function agreement. The projector is applying some EOTF, possibly a configurable “gamma” setting somebody changed in 2019, and it is probably not the one your file assumes.
Ambient light. This is the big one and it is not a colour-management problem at all. A projector cannot produce black — it can only fail to add light, and the screen is still lit by the room. Your blacks are whatever the ambient light makes them, so your entire contrast ratio is determined by how dark the gallery is. The washed-out look is usually this.
White point. The projector’s white may be noticeably warmer or cooler than your D65 monitor, which tints the whole image.
The practical order of operations: control the room light first, because it dominates everything else and costs nothing. Then set the projector’s EOTF to match your content. Then worry about gamut. Checking a grey ramp and a known skin tone on the actual projector, in the actual room, at the actual ambient level, will tell you more in five minutes than any amount of reasoning from specifications.
The short version
- An RGB triple is an instruction to a device, not a colour
- A colour space is three things: primaries, transfer function, white point
- Non-linear encoding is perceptual compression, not a legacy accident
- OETF and EOTF are different and deliberately not inverses
- Gamut mapping is a choice with no correct answer
- ACES is a hub-and-spoke pipeline, not just a wide space
- On a projector, the room is usually the problem