Physics Stack Exchange is a question and answer site for active researchers, academics and students of physics. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Starting with xy coordinates I would like to plot a chromaticity diagram displaying just the sRGB gamut portion of the CIE xy chromaticity diagram.

For each xy coordinate of my diagram I need to determine the corresponding Y value to obtain the complete xyY representation, from which XYZ tristimulus values can be calculated and finally sRGB values derived.

By starting with the known sRGB Red, Green, Blue and white values: #FF0000, #00FF00, #0000FF, #FFFFFF respectively I can use the Bradford matrix to deduce their XYZ tristimulus values and thus their xyY representations.

But starting with xy coordinates is there a method for determining the Y component?

ps. If you are able to add new tags, could you possibly add some tags like 'colorimetry', 'chromaticity-diagram' and 'color-models'?

share|cite|improve this question
up vote 1 down vote accepted

The Y component is for you to choose, because for a given x,y pair, depending on Y, the colour may or may not lie within the sRGB volume.

It is possible to know whether there is at least one sRGB colour that will map to a given x,y pair, though. Note that if linear RGB values (R,G,B) are transformed to (x,y,Y), then (a*R,a*G,a*B) are transformed to (x,y,a*Y). Multiplying each of the RGB triplets with a constant doest not affect x or y.

So one way to take an (x,y) pair and find out whether it can be obtained from an sRGB value is:

  • set Y = 100
  • convert (x,y,Y) back to (X,Y,Z)
  • convert (X,Y,Z) to linear RGB (R,G,B)
  • if one of R, G or B is negative, we are out of the sRGB space
  • otherwise, divide each of R, G and B by the largest of the three
  • optionally, convert linear (R,G,B) to gamma-corrected sRGB values

Here is some GLSL code that does the job:

vec4 color = vec4(0.0, 0.0, 0.0, 1.0);

vec3 xyY = vec3(pass_Position.xy, 100.0);
vec3 XYZ = xyY.z * vec3(xyY.x / xyY.y, 1.0, (1.0 - xyY.x - xyY.y) / xyY.y);

mat3 XYZtoRGB = mat3(vec3( 0.032406f, -0.009689f,  0.000557f),
                     vec3(-0.015372f,  0.018758f, -0.002040f),
                     vec3(-0.004986f,  0.000415f,  0.010570f));

vec3 RGB = XYZtoRGB * XYZ;

if (RGB.x >= 0.0 && RGB.y >= 0.0 && RGB.z >= 0.0)
    RGB /= max(RGB.x, max(RGB.y, RGB.z));
    vec3 sRGB = pow(RGB, vec3(1.0 / 2.4)); = sRGB;

And this is the result:

sRGB gamut

share|cite|improve this answer
Hi Sam! thank you very much for your answer. Sorry for the slow reply I'm still new to working with colour models and wasn't sure if I had more questions but I think I'm ok for now. Thanks again! – Duncan Gravill Feb 26 '13 at 13:34

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.