Color space experiments

tags:: sketchbook
date:: Jun 17th, 2023


Color matching functions

CIE 1931 RGB color matching functions:

source: https://ia802802.us.archive.org/23/items/gov.law.cie.15.2004/cie.15.2004.pdf

CIE 1931 XYZ color matching functions (analytical approximation):

source: https://en.wikipedia.org/wiki/CIE_1931_color_space

CIE 1931 XYZ color matching functions (table):

source: https://files.cie.co.at/CIE_xyz_1931_2deg.csv

Transformed via RGB matrix:


RGB chromaticity:

RGB chromaticity transformed to XYZ:

XYZ chromaticity:

XYZ chromaticity (from analytic approximation):


Let’s create a spectrum. Take the original color matching function. Since that is telling us the XYZ values needed to create a spectral color, shouldn’t we be able to iterate over the wavelengths of visible colors (400-720), get the XYZ values for each one, and convert them to RGB and render a spectrum?

This looks pretty bad, but why? I found a nice article about rendering spectra which seems like another deep hole. My problems aren’t even close to that kind of accuracy; the above isn’t remotely close.

Turn out I need to convert XYZ to sRGB because that’s what the rgb() color function is assuming when rendering to canvas. The main difference is gamma correction which is another topic.

I wanted to test out the p3 wide gamut color space. I ran into the same problems before, which was surprising because everything I read implied it was linear. Turns out the p3 color space in browsers has the same gamma correction as sRGB, so I needed to include that to get it to work:

If you are seeing this on a wide gamut compatible browser (safari) and display, you will see more intense colors (particularly reds).

Question: why does printing use the CMY color system with the primaries of cyan, magenta, and yellow, while digital displays build pixels with the primaries of reg, green, and blue?

Now we need to generate some spectrum and the resulting color… get the integral

Take this spectrum:


Rendering the chromaticity