Skip to content

Instantly share code, notes, and snippets.

Last active February 15, 2024 00:54
Show Gist options
  • Save Myndex/10caff6a68e844591e83eadeebfb4347 to your computer and use it in GitHub Desktop.
Save Myndex/10caff6a68e844591e83eadeebfb4347 to your computer and use it in GitHub Desktop.
A discussion that continues the Lab/Luv Gist. This one on working spaces and whitepoints.

Will Work For Color

Color Manglement and Working Spaces.

A continuation of the Lab/Luv Gist

Let's not forget the many other color appearance models and methods. CAM02-UCS, RLAB, LLAB, IPT, CAM16 which is Luo's work in progress, etc. Many choices beyond the 44 year old Lab. The fact that Lab is one of the PCS used in ICC profiles is notwithstanding. If you look through profiles, you'll see that Lab is typically used as a PCS in profiles for CMYK and printing, while RGB space and monitor profiles use XYZ for the PCS.

Among other things, XYZ is computationally simpler than Lab. XYZ is infinite/unbounded••, you can transit through it without much penalty assuming the same source and destination illuminant (D65), here the fact the PCS is "D50" is essentially irrelevant: we are never really "in" D50, just passing through. Gamut mapping, soft clipping, etc. are usually not a huge concern going from a D65 RGB to another D65 RGB especially if the gamma is linear and we are unbounded (32 bit float).

••SIDE FOOTNOTE: Yes, the ICC says to clamp XYZ at 0 and 1, but in linear 32 bit float, clamping is not needed until you're ready to gamut map.

The bigger point is, it does not matter hugely if you are in linear RGB, then transit through XYZ, a linear space, and use the non-standard D50 as the reference point.. so long as you are not doing any "work" in D50 when your source and destination are both D65. The problems start to crop up when your source and destination is an RGB D65 and you start using D50 LCh for a working space. And it's not about round trips, it's about things like gamut mapping, and things like converting to your D65 monitor space for viewing and soft proofing and the inherent errors that creates in your viewing space.

Modeling Appearance

On the other hand, Going from a D65 RGB to a D50 CMYK you need something that relates more to appearance than the mere colorimetry. When the ICC was formed in 1993, CIELAB was the best-in-class perceptual color model for reflected surfaces such as printing, graphic arts, textiles, paint, etc.

On D50: D50 is used in the printing/graphic arts industry, and essentially no other. Virtually all other industries including paper, ink, paint, textile, the Film and Television industry, etc. use the CIE standard illuminant D65. (Except Digital Cinema DCI P3 is DCI White 6300K and XʹYʹZʹ with a 1/2.6 gamma, and some ACES specs).

And related, ICC by their own admission is weighted for the print indistry — for web content on self illuminated displays the ICC paradigm is less than ideal, in fact it's a 200-pound cast-iron boat anchor being used for a 1 person canoe, and I cannot support the print industry telling the web content industry how to handle color! UGH!

Lab (and D50) are a part of ICC, and D50 was chosen as ICC is/was largely focused on enabling desktop publishing and physical printing while using your monitor for soft-proofing. The process is "quasi-accurate" and dependent on the surrounding support hardware and software. Nevertheless, ICC is fairly useable for desktop pre-press, and as a container for display profiles.

But ICC color management takes up significant CPU resources, and there are a lot of use cases where they are best to avoid, particularly for video playback, mobile, and other situations where performance is key. Using ICC management in a video player or editing app can mean the difference between playing at full-speed full-resolution, and playing a quarter size whilst dropping 70% of the frames.

On that note, A Dough Bee tried to shove ICC profiles into the film and television industry by adding ICC to AfterEffects in 2008, (and into Premiere 2018), and the results are mostly disastrous (I know, painfully I was an early adopter before realizing that ICC color manglement is not suited to film/television work.) Other VFX and Editing apps use calibrated and/or LUT based workflows, and Sony's free open-source OpenColorIO LUT extension opened that up for AfterEffects, so any serious AE VFX artist is using OCIO LUTs and not ICC profiles.

Straight Talk About Linear

OpenColor IO is free and open sourced, and there are good fits for web content workflows, especially for linearized working spaces.

Linearized unbounded spaces can be useful. Though I do read some comments that make linear working spaces to be the "only best way" and that is not completely true. Linear is good for compositing and modeling real-world light, as real light is linear. In other words, if you have 100 photons of light and double it, you then have 200 photons. But we as humans do not see it as a doubling, our perception is not linear.

As a result, linear is not necessarily the right colorspace for some uses, such as graphics, web design, color mixing, gradients, and anywhere you're working with "perceptual" elements. I.e. sometimes you want a working space that models light, and other times you want a working space that models perception instead. This is an important difference that I discuss with examples in Part One and Part Two of "Gradients in Space", but here's a few of the examples.

These four gradients were created using (from left to right) sRGB, xyY (linear), L*a*b*, and LCh (from Lab).

Screen Shot 2019-05-24 at 9 23 07 PM

Four different spaces/methods, and four very different results. On first glance it might seem that the LCh is the most dynamic , good if that is your design goal... but look at this next slide, from saturated color to achromatic...

Screen Shot 2019-06-19 at 9 30 28 PM

YIKES!! LCH mangled that all to hell! When going from a saturated to a less saturated or monochromatic color, you probably don't want nearly as much hue movement. But also notice that the sRGB and the LAB look almost the same. This is to be expected. The gamma for sRGB is roughly 2.2 and the effective gamma for LAB is about 2.38, in other words, when it comes to the lightness curve, there is very little difference between sRGB and L*, if the gradient is not shifting hue, then you are not likely to notice much of a difference.

In this next slide notice the LCh version is very colorful — but that's not a good match for the start and end colors:

Screen Shot 2019-05-24 at 9 27 08 PM

In this case, we need to be able to each and trim the LCh results. IN the next slide, there was a chroma reduction in the middle of the gradient:

Screen Shot 2019-05-24 at 9 27 25 PM

And in many cases, you may want to ease in or out at the start or end or both. THE POINT: no single colorspace is "best" for all occasions.

Working Space and Whitepoint Wrap-Up

So for working spaces for web content, we may want to use a linear space, or we may want to use a perceptually encoded space, or if we want the best performance such as for streaming, then we want to use the native space.

Best Performance

That said, the best performance space (as of this writing) is 8bit sRGB D65, the default standard for the web. While not perceptual, the gamma (trc) makes it "close enough" to a perceptual space for reasonable gradients and color mixing. And while not linear, this kind of gamma-encoded space has been used for decades and the methods & math for compositing in this space are well understood (i.e. 'screen', alpha scaling).

And sRGB being standard works with no color correction or gamut mapping assuming the author ensures everything is sRGB. What is gained is maximized performance in display, streaming, download times, etc.

Other Native Spaces

Ideally and for best performance, a working space for CSS color would match the native space of the destination device such that that device would not have to perform any color correction, and everything would work like a "calibrated space" which is what television is.

This could probably be handled with media queries, though I am sure there are some security concerns.

Best for Compositing

The best working space for modeling light, compositing images, and many image effects like resize, blur, etc, is usually a linear RGB space. It can be pretty much any RGB with the gamma (or TRC) removed (i.e. gamma = 1.0). These use cases cannot be 8bit, they should be at least 16bit float, white point should remain D65, white mapped to 1.0, and black to 0.0, and knowing that these are not clamped values and may be exceeded.

This implies the need for gamut mapping or highlight clipping to get back to a display space like sRGB. While linear is great for the specific use cases, it's generally a resource hog and requires additional diligence in terms of transforming to a final output which will require some form of color management, gamut mapping, transform to a display space.

Best for Perceptual Tasks

If your needs are not compositing, blurring, modeling light, global illumination, etc, but instead you want the color controls to "feel" natural relative to perception, then one of the spaces this entire article about is probably what you want. Luv, Lab, LChuv etc etc...

Since this use case is a working space coming from D65 and displaying to D65, D65 is the white point that should be used for the working space. Normally Lab uses the standard D65 illuminant, such as in the textile industry, the paint industry, and for pretty much all of the monitors and mobile devices using the web.

Normally Lab, Luv, Lch use floating point values, and these spaces are also processor hogs, perhaps not as much as a linear space. Nevertheless, there are similar concerns regarding gamut mapping prior to output, though not as severe as with a linear working space.

All This Space and No Where To Go Fast

A final question here: Should an entire page be in anything but the destination space? It seems wrong actually to send a page in a "working space" with a profile to unwind it at the destination. At the same time, serving up a bunch of pages designed in a linear space and processing them dynamically before sending to the client would be a pretty severe server load.

The ideal solution then is to send a page at the native colorspace for the destination, with async (JS ?) elements that need processing within fenced-off sub-working spaces for linear or Luv etc.

In this same vein, ICC color management and ICC profiles may not be a great choice due to their inefficiency. Everything for web content display is D65, a more direct processing approach can be used to good effect, and using a vectorized JS math library may be a key to this compartmentalized "Working Spacelets" approach.

— Andrew Somers Nov 2020

Copy link

p {
font-size: 1rem;
font-weight: normal;
line-height: 1.3;

a:link {
font-weight: bold;
text-decoration: none;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment