Hacker News new | ask | show | jobs
by panic 3425 days ago
Paste this into the editor to see the difference:

    varying vec3 vPos;
    
    float sRGB(float x) {
       if (x <= 0.00031308)
          return 12.92 * x;
       else
          return 1.055 * pow(x, 1./2.4) - 0.055;
    }
    
    void main() {
       float v = (vPos.y + 1.) / 2.;
       if (vPos.x < -0.5)
          gl_FragColor = vec4(pow(v, 1./2.2));   // 2.2 Gamma
       else if (vPos.x < 0.0)
          gl_FragColor = vec4(sRGB(v));          // sRGB 
       else if (vPos.x < 0.5)
          gl_FragColor = vec4(sqrt(v));          // sqrt approximation
       else
          gl_FragColor = vec4(v);                // unadjusted
    }
The sqrt() function adjusts for the output curve of your display (usually sRGB nowadays, but in the past various gamma values have been used). The strips on the left should have an approximately linear gradient between light and dark, whereas the rightmost gradient will be too dark.

The question of why your display doesn't just output linear colors is more interesting. Small differences in dark colors are more easily perceived than differences in lighter colors, so it's useful to spend more encoding space on the low end. With more bits, you could use linear colors throughout, but all color data would take up proportionally more memory. It ends up more efficient to just decode from sRGB, do your computation, and encode into sRGB again each time.

Modern graphics APIs can automate this sRGB coding for you by letting you specify an sRGB format for textures: each time you read from an sRGB texture, the system will decode the color into linear space, and all writes will automatically encode back into sRGB.

1 comments

WebGL + GLSL should already adjust this for you, giving a linear colorspace. Notice that 'unadjusted' actually looks correct (at least on my browser, Chrome @ Linux).
Should as in "it would be nice"? Maybe.

Should as in it does already and this sort of thing is unnecessary? Definitely not. Hence EXT_sRGB.

Should as in "I believe WebGL + GLSL already does this by default, it does at least on my machine".
This would be in violation of the standard (in a way that would cause a lot of things to render wrong -- anybody who was rendering correctly would now be wrong!), and also it isn't practical in most cases.

It's a common misconception that this is taken care of for you by <platform X>, but it basically never is. I'm positive this is the case for WebGL.

Linear is not a colourspace.

It is an attribute of a properly defined encoding model. Further, there are two forms of linear display linear and scene linear, which are fundamentally essential to grasp for rendering approaches.

See ISO 22028-1:2004 for a discussion of terms.

> Linear is not a colourspace.

I never said so. I said it gives >> a << linear colorspace. There are many such color spaces. Some are linear in different aspects (better at close or far away colors), and some only preserve some aspects (linear in brightness, or chroma, etc). I didn't intend to fully go into color theory.

I'm not even certain how well defined the color space is, and how properly linear it is. I do know that it accounts for gamma correction though (at least on my machine).

No.

Linear is not a colour space, as a properly defined colour space, as per the ISO specification, is:

- A well defined transfer function.

- Properly described primary light chromaticities.

- Properly defined white point colour.

Where you reference "there are many such color spaces" is the issue. Linear specifically relates to the first point, and even that doesn't properly describe whether one is speaking of display linear or scene linear.

The other points relate to perceptually uniform discussions, which would be a misuse of the term linear.

I agree that it is not a suitable forum for color theory. “Linear” however, is a much confused subject, worthy of explanation.

Unadjusted looks correct for me in Chrome and Firefox in Fedora. I have an nvidia card so I'm not using Wayland, I'm not sure if that would make a difference.