Display P3 vs sRGB in Color Palettes
Sun, 08 Apr 2018 17:44:37 +0100
In my previous blog post I talked about the Display P3 color space, a wide gamut RGB color space used by Apple. I tried to visualize the difference between displayP3 and sRGB colors using Self-Organizing Maps, but they were of no much use to see visualize the difference.

Since then, I've been working on an app I called Palettist to compute color palettes using Display P3. The app, still not out in the App Store, includes two interesting options to produce examples of displayP3-only images. First, you can select "displayP3 - sRGB" as the input color space, so only colors outside the sRGB gamut, but inside the displayP3 gamut, are used in the color palette. Then, you can select an "sRGB comparison shape" to render a shape inside each color bin where the color is clamped to its equivalent color in sRGB color space. This is great to evaluate different displays and Display P3 capabilities. Check the online manual for details.

Here's the first example of displayP3 only colors:

You could be seeing several things now:

  • If you are reading this on a browser like Safari that understands 64-bit PNG images with an embedded Display P3 color profile AND a display that can display that gamut, then you should see circles inside each color bin/square. The color of the squares are in displayP3, and the color of each circle is the color of its surrounding square, clamped to sRGB color space. You can see that sRGB colors are more dull. For some colors, the differences are very small. But there's definitely a circle inside each one.
  • If you don't have a displayP3 display, but your OS/browser is doing proper color management, then you shouldn't see any circle. You should see this,

    I created this image by converting the one above to sRGB using GIMP. The two images should look the same if you have an sRGB display.

  • If you don't have a displayP3 display, but you see circles, I suspect you may not have proper color management. What happens is that some programs ignore the color profile and interpret the RGB triplets in each pixel as if they were in sRGB color space. That means that the squares look like what the circles were supposed to look like, and the circles now look even duller. You would be seeing this,

    I created this image by embedding the wrong color profile, sRGB, to the first one. Everyone should be able to see circles in this image, but all these colors are now inside the sRGB color gamut.

Display P3 color palettes by color category

For reference, I've created more of these displayP3-only palettes, clustered by color category, so it's easier to appreciate the gamut differences depending on the color.

Light brown










You can make a few observations from here:

  • there are no black, gray, or white colors;
  • there are only a few browns, and you can't barely tell the difference from their sRGB counterparts;
  • greens are the most numerous;
  • there are a lot more blues than I originally expected, but I think it's because of the greencomponent in cyan-like blues. Although the blue channel is also more intense than in sRGB.

If you inspect the difference of displayP3 and sRGB in Color Sync Utility (or check my previous blog post), I think the observations above are consistent with the shape of the volume difference.

Display P3 in Metal SDK

To close, just some programming notes. It took me a while to figure out how to render displayP3 colors in Metal. I wrote an extensive post in Stack Overflow. I'll summarize here the main points.

MTKViews have a colorSpace property in macOS, but not on iOS. I suspect the difference is because color management on iOS is targeted (see Best practices for color management). So how does it work, then?

The solution is simple. You can set an output surface in Metal with a texture in extended range pixel format. For instance, bgra10_xr_srgb. When you do this, if you output (1, 0, 0) in your shader, you will obtain the expected sRGB red color, but if you make its value greater than one, the color will be even redder (provided that your iPhone/iPad display supports it), and it will fall inside the Display P3 gamut.

So if your rendering pipeline assumes Display P3 linear color space all the way through, before you render your colors to the output texture, multiply by the 3x3 matrix that linearly converts from displayP3 to sRGB (you can find the matrix in my previous blogpost). DO NOT CLAMP OR SATURATE the output! Some values will be negative, and some will be greater than 1. And that's OK. Just make sure the pixel format of your output texture is one of the extended range ones. If it ends in "_srgb", it will also apply the gamma for you.

And that's all! Check the Stack overflow post for details.

Please let me know if this is useful to you. Also, please download Palettist and try generating some displayP3 palettes yourself 😊 Come back here or follow me on twitter to find out when the app gets published. Hopefully, somewhere around next week, if Apple doesn't find any issues. I'm a bit anxious because it's the first app I release using a Metal-only library, my VidEngine. Wish me luck.


Previous year

Next year