Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Having worked on this in Skia (and so Chrome, Android) for a good while, I can vouch this is an issue browser/phone developers would have liked to fix a long time ago, but have kept by default for compatibility with old expectations. A lot (~all) of web/app design was and still is done with this broken interpolation in mind, which then all breaks when math is done in a way that more accurately models light.

It’s a bit of a chicken and egg problem that we can really only fix by allowing content to explicitly opt-in to linear working color profiles. And sadly that’s not going to solve everything either: while a linear profile is good for color interpolation, sRGB encoding is ideal for brightness interpolation. You’re stuck choosing between ugly red-green interpolation and nice white-black (sRGB) or between nice red-green and ugly white-black (linear). There are some more complex color spaces that do try to be the best of everything here, but I’m not aware of any browser or OS providing support for working with these perceptual color spaces.

A similar problem comes up when trying to manage color gamut on screens and systems that are intentionally blown out to look vivid, vibrant, shiny… looking at you Samsung phones. Any properly color-managed image there looks incredibly dull compared to the bright defaults you’ve grown accustomed to. If we take 0xff red to mean “full sRGB red”, that’s much less bright these days than if we just assume it means “as red as the screen will go.” It’s much like how TVs are (hopefully were?) set in the store in bright shiny mode to induce you to buy them, not set to reproduce colors accurately.



> There are some more complex color spaces that do try to be the best of everything here, but I’m not aware of any browser or OS providing support for working with these perceptual color spaces.

OKLab and OKLCH coming soon to CSS4 near you:

https://www.w3.org/TR/css-color-4/#resolving-oklab-oklch-val...


It's already shipping in Safari 15.4!

Note this is a part of what the "Color Spaces and Functions" area of Interop 2022 (https://webkit.org/blog/12288/working-together-on-interop-20...) contains. See https://wpt.fyi/interop-2022?feature=interop-2022-color for the current status.


Oh that’s amazing! OKLab looks really good to me!



OKLab is great. AFAIK even Photoshop uses OKLab to interpolate gradients.



well, that was fast :)


> A similar problem comes up when trying to manage color gamut on screens and systems that are intentionally blown out to look vivid, vibrant, shiny… looking at you Samsung phones.

This is a problem on a lot of HDR-capable consumer monitors, even expensive factory calibrated ones from Dell. They often lack any form of sRGB clamp resulting in exactly this problem when viewing an sRGB signal. AMD has a setting in their GPU driver control panel that can do this on the GPU without needing the user to provide an ICC profile. The Nvidia driver has a hidden API to do this, requiring the use of third party software to take advantage of.[1]

TVs are a little better in this regard. My Samsung TV has an "Auto" option for color gamut that correctly identifies DCI-P3 and sRGB signals and clamps them accordingly. But the default setting was "native" which made sRGB content look really bad.

1: https://github.com/ledoge/novideo_srgb


>They often lack any form of sRGB clamp

And the ones that don't almost universally lock you out of all other color settings when enabling it, often even including brightness. It's ridiculous.

Also, thanks for the shoutout :)


> A similar problem comes up when trying to manage color gamut on screens and systems that are intentionally blown out to look vivid, vibrant, shiny… looking at you Samsung phones. Any properly color-managed image there looks incredibly dull compared to the bright defaults you’ve grown accustomed to. If we take 0xff red to mean “full sRGB red”, that’s much less bright these days than if we just assume it means “as red as the screen will go.” It’s much like how TVs are (hopefully were?) set in the store in bright shiny mode to induce you to buy them, not set to reproduce colors accurately.

I remember when the Pixel 2 came out, there was a minor kerfuffle over it defaulting to using sRGB. It got overshadowed a bit due to some of the more severe issues people ran into with the early batch, but it still apparently got enough of a backlash for them to patch it shortly after to update to a compromise between what I think it called "natural" and "vivid". At the time, I had never paid much attention to color profiles, so my roommate suggested I enable sRGB (which was in the developer settings on the original Pixel) for a week and see if I preferred it. It turns out I do actually prefer it, so now I've used it on whichever phone I've had since then!


Unmanaged color on wide-gamut outputs is simply godawful. I'm not surprised consumers go for it in direct comparisons, but especially with dark color schemes in vogue it seriously hampers usability by crushing darker shades (at least when lerping to DCI-P3).

TVs and monitors are pretty bad as well, but at least more wide-gamut source material is becoming available and calibration to DCI-P3 or Rec.709 is starting to become a selling point.


The article mentions the color-interpolation attribute.

Chicken-and-egg problems have to be resolved one step at a time. Implementing color-interpolation is a possible first step.


Would a new web standard that allows web developers to configure a 'color rendering mode', either on a webpage as a whole or individual parts (e.g. via a css option) solve this issue?


In what way is linear black-white interpolation ugly?


Oh sorry, yeah ugly is a really subjective term, I should have explained.

The 0.5 sRGB grey (aka 50%, 0x7f or 0x80) is right smack at the grey value most people would pick as the halfway point between black and white.

A linear 0.5 grey is way off from that, I think way too bright, but I’m about 10 months off working on this and to be honest this is one of those things like east/west or left/right that I can never remember without working out the math on a piece of paper. Too bright or too dark for sure, not at all a medium grey.

It took my team a long time to not think of linear and sRGB interpolation in terms of good vs. bad, right vs. wrong, modern vs. legacy, etc. There are good uses for interpolating in both color spaces, and an a variety of others like HSL, HSV, CMY, perceptual spaces. Sorry for continuing the problem. There’s no ugly color space; they all have good uses.


If you want to simulate light at a physical level (even as simple as two projectors shining light at the same wall) then Linear Light is correct —- it is any time when your mental model includes ‘light’… It just works.

You are right though that schemes like sRGB are a better fit for perceptual brightness. As you say the slider works the way people expect it to and you don’t need so many gray levels. 8 bit linear light shows posterization at some levels and is shaded too finely at others. If you want good results with linear light and common tools you need 16 bits of grey.


What I use is HSL whereby the H is in LRGB and the L is in SRGB (I forget what the S is but it’s one of the two). Very simple way of getting the best of both worlds when doing color math.


https://i.imgur.com/CRq6Kn8.png (left: linear, right: sRGB)

In linear interpolation, there's too much white and not enough black. That's why gamma correction/sRGB exists after all: if you encode the linear value directly, you waste most of the space on white values you can barely tell apart.


Sorry but this is just your example being horribly misgenerated/some gamma being applied twice, maybe even thrice. Here is what I generated:

sRGB: https://i.imgur.com/dbn3TM6.png Lab (linear): https://i.imgur.com/dCXzbF3.png

Please download the images and view in a proper image viewer. For some reason at least on my Windows machine Google Chrome adds horrible color banding to both images.

This is my code:

    import imageio
    import numpy as np
    import colour

    quantize_with_dither = lambda im: np.clip(im * (2**8-1) + np.random.uniform(size=im.shape), 0, 2**8-1).astype(np.uint8)

    srgb_black = [0, 0, 0]
    srgb_white = [1, 1, 1]
    srgb_grad = np.linspace(srgb_black, srgb_white, 500) * np.ones((200, 1, 3))
    imageio.imwrite("srgb.tif", quantize_with_dither(srgb_grad))

    lab_black = colour.XYZ_to_Lab(colour.sRGB_to_XYZ(srgb_black))
    lab_white = colour.XYZ_to_Lab(colour.sRGB_to_XYZ(srgb_white))
    lab_grad = np.linspace(lab_black, lab_white, 500) * np.ones((200, 1, 3))
    lab_grad_in_srgb = colour.XYZ_to_sRGB(colour.Lab_to_XYZ(lab_grad))
    imageio.imwrite("lab.tif", quantize_with_dither(lab_grad_in_srgb))


I didn't trust imageio's correct handling of gamma/colorspaces so I just wrote out the raw sRGB coefficients as 8-bit TIFF and used imagemagick to convert to PNG, telling it that the input is in sRGB:

    magick convert lab.tif -set colorspace sRGB -depth 8 lab.png
    magick convert srgb.tif -set colorspace sRGB -depth 8 srgb.png


Lab is not linear. L predicts perceptual brightness, just like sRGB, which is probably why your two gradients are almost the same.

Gamma encoding is lin_to_srgb(c) = c*12.92 if c<=0.0031308 else 1.055*c**(1/2.4)-0.055. Since lin_to_srgb(0.214)=0.5, in a linear ramp, the middle gray (808080) pixel should occur about 20% of the way through.


That banding is odd. I get the same issue on Windows 11 latest Chrome build. Looks fine in Windows default image viewer. These are PNG images, so there is no decompression to mangle them. The only way the two images could differ is in the way the pixels are massaged into the color space. Weird.


I've generated my own version of this (i just happened to be working on something that needed gamma correct rendering)

https://i.imgur.com/jeM4RCu.png

       top: linear_to_srgb(x)
    middle: x
    bottom: srgb_to_linear(x)


It’s probably just that a gradient between black and white in linear RGB results in a gradient with a midpoint that doesn’t look like _the middle between black and white_ to the human eye. I far as I understand that’s what sRGB fixes, perhaps among other things, and the way it fixes that results in muddy colors when you mix different colors.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: