Rendered at 13:40:38 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
20k 14 hours ago [-]
This article contains some pretty major errors, which is kind of surprising to see!
>The transformation used to represent the physically linear intensity data either generated synthetically via an algorithm or captured by a linear device (such as a CMOS of a digital camera or a scanner) with the discrete values of the perceptually linear scale is called gamma encoding.
This isn't super correct, and it underscores the biggest issue in this article:
sRGB (and its gamma encoding function) has absolutely nothing to do with perceptual linearity. sRGB is not perceptually linear! The original gamma encoding as far as I'm aware was made to compensate for the nonlinear transfer function of CRTs back in ye olde days. Its true that human vision is nonlinear, but sRGB is not a particularly good match to the perceptual linearity of human vision. Its a really common error to make, and leads to people wondering why we can't use sRGB to blend in if the reason why it was invented is because its perceptually linear
The article goes to compound on this mistake, which is why this is such a problematic misconception:
> Interestingly, Photoshop antialiases text using γ=1.42 by default, and this indeed seems to yield the best looking results (middle image). The reason for this is that most fonts have been designed for gamma-incorrect font rasterizers, hence if you use linear space (correctly), then the fonts will look thinner than they should.
This is where the mistakes start to add up
Consider what you're trying to achieve during antialiasing: when rasterising a line, lets say we discover that a pixel is only 40% covered and want to darken it. This means that we want our pixel's brightness to decrease by 40% to a human being. We don't want to emit 40% less light, because that's not what antialiasing is trying to achieve!
Both sRGB and linear colour are the wrong colour spaces to use. You want to blend in a perceptually linear colourspace, and photoshop's 1.42 gamma exponent probably maps better to human vision than 2.2 or 1.0 while being cheaper than a LUV conversion
>The standard gamma (γ) value to use in computer display systems is 2.2. The main reason for this is because a gamma of 2.2 approximately matches the power law sensitivity of human vision
The gamma transfer functions are also wrong. Its worth getting hung up on because it actually causes nontrivial errors, especially in the age of hardware accelerated sRGB conversions where doing it correctly is free
vektorsigma 11 hours ago [-]
When antialiasing, I think you do want to model light: a fully black object occluding 40% of a pixel should cause it to emit 40% less light. Linear intensity representations of colour should therefore be used.
When doing a smooth fade-to-black in video, you may want to gradually decrease the amount of emitted light from the whole frame in a way that is smooth to a human. Here I think you should consider how a perceptual space can help.
20k 5 hours ago [-]
>When antialiasing, I think you do want to model light: a fully black object occluding 40% of a pixel should cause it to emit 40% less light. Linear intensity representations of colour should therefore be used.
The antialiasing value you get represents how much the pixel is covered by the glyph in question, and directly represents a desired change in perceptual brightness. There's no physical underlying lighting process, so it doesn't make sense to use physical light units
Blending in linear RGB models different strength lights being mixed together. This is why you do want to blend images together in linear RGB, but not fonts - because its not an underlying light based transport process
To take a direct example: Imagine two cases
1. We blend a white font on a black background
2. We blend a black font on a white background
Using perceptual blending, the antialiasing will be exactly the same efficacy in both cases. Using blending in linear space, these two test cases will look very different and render incorrectly!
brookst 2 hours ago [-]
Also consider blending different levels of grey. Blending 20% to 0% versus 40% to 60% versus 80% to 100% will look wildly different.
adrian_b 3 hours ago [-]
As you, say the original purpose of gamma was strictly to compensate the non-linearity of CRTs.
The reason why gamma has been preserved in digital television even after CRTs have become obsolete is that it happens to perform a dynamic range compression that allows the use of 8 bits for luminance or for color components without making too visible the steps between adjacent color values.
If you want to encode the color components linearly, you need to use more than 8 bits, preferably the FP16 format, which was originally introduced in GPUs especially for this purpose.
So today the only purpose of gamma is as a method of data size compression that is specific to images, by allowing the reduction of the number of bits per pixel, while keeping acceptable the degradation of the image quality.
It is probable that the standard gamma curves are not optimal for data compression, but the slight improvements in image quality that could have been attained with other curves are not worth the complications that would have been created by abandoning the compatibility with legacy recordings.
arghwhat 50 minutes ago [-]
Just a nit: Post-CRTs, there is no longer a "standard gamma curve", but many different transfer functions and many errors stem from misunderstanding this.
Even within "SDR"/"sRGB", many mistakes crop up from people erroneously mixing content encoded with the piecewise sRGB transfer function with content encoded according to a plain gamma 2.2 transfer function. And this is before we are getting into e.g., incorrect blending spaces or mismatched primaries.
But yes, it is purely a matter of compression, with many options for exactly what dynamic range you need and how you want your content defined (e.g., sRGB, gamma2.2, scRGB, HLG, PQ, ...), with linear light primarily reserved as an intermediate space for color conversions and blending - something your display server and any software working with arbitrary color spaces will be using.
adrian_b 4 minutes ago [-]
That is why I said "standard gamma curves", and not "standard gamma curve", as each standard specifies a slightly different curve, for various reasons.
Such differences in standards already existed in analog television, because, depending on how they were made, the CRTs also had slightly different transfer curves from grid voltage (where the video signal was applied) to anode current (which is proportional with the luminance of the pixel component), and the regional TV standards accounted for the dominant manufacturers of the CRTs sold in that region.
joedrago 9 hours ago [-]
For those interested in this topic, I found minutephysics' treatment of this subject to be really pleasant and easy to grok. I had a talk I gave at work once or twice discussing color conversion and I would play a 90 second snippet from this (attributed appropriately) as it would very quickly crash course people on the reasoning behind an EOTF in a really cute and layman's terms kind of way:
I work on the open-sourced Jedi Academy game engine, which is based on id tech 3. It has special logic to specifically adjust the gamma of the physical monitor during launch, then restore it upon exit.
This is why when these older games crashed on your PC, the monitor would look all washed out due to the manual gamma adjustments the game made that didn't get restored.
joedrago 9 hours ago [-]
Nice! I remember being an early Nvidia adopter (RIVA 128, TNT) when all of my fellow LAN party buddies were Voodoo users, and I had to download a custom opengl32.dll which actually adjusted the gamma into tolerable levels so you could see what was going on in Quake.
Dwedit 8 hours ago [-]
This kind of thing is why you need a separate watchdog process that gets notified when the other process terminates.
zokier 17 hours ago [-]
for lot of image processing linearizing srgb is only half-way measure, and you might want to reach for a better colorspace altogether. cielab is obvious example, or maybe oklab/jzazbz/xyb/something else.
raphlinus 16 hours ago [-]
Exactly this, there's rarely a single "correct" colorspace, you make a choice based on expressive goals and constraints. For example, for gradients you almost never want linear, something like Oklab is indeed much better.
The gradient examples between high-chroma colors of similar luminance are highly misleading in my opinion. In that particular case, linear just happens to do well (and device RGB of course poorly), but in other cases linear is not great. For example, blue to white is especially bad, with hue shifts as well as lightness non-uniformity.
You can experiment with this in the interactive tester in my Oklab review[1].
Depends. Many times a linear colorspace is exactly what you want.
Espressosaurus 11 hours ago [-]
Linear light, or linear perceptual?
leni536 2 hours ago [-]
Linear light (if that really is a term of art).
shaggie76 15 hours ago [-]
ICC profiles present a similar problem and remarkably Instagram, ostensibly a photo-sharing web-site, does not respect them when scaling images (or at least it didn't a few years ago when I started posting photos to it from my PC); when I uploaded full-resolution SLR-resolution originals the skin-tones would get all screwed up. If I exported at the final resolution, even with the same ICC profile, they were fine.
> [...] the only reason to use gamma encoding for digital images is because it allows us to store images more efficiently on a limited bit-length [...]
It's interesting how this part of the trade-off changes when using float16 for color components (as is common when HDR is involved) rather uint8.
Good timing that Safari 27 adds support for srgb-linear and display-p3-linear color spaces.
keynha 12 hours ago [-]
[dead]
hatthew 14 hours ago [-]
This feels like less of a gamma issue and more of a color space and monitor calibration issue. Possibly affected by the fact that oklab didn't exist when this article was written and the general awareness of color spaces was lower.
dheera 17 hours ago [-]
> On which image does the gradation appear more even? It’s the second one!
I felt the first one looked more even. On the first I could tell the difference between every two adjacent bars. On the second one I couldn't tell any difference between the first 4-5 bars.
tobr 15 hours ago [-]
Probably because it’s displayed on a white background. A gray or black background would have shown the difference more clearly.
account42 2 hours ago [-]
No it's because #000 isn't actually black on a physical monitor, especially a backlit one so you loose contrast which affects the lower end of the range more than it does the brighter colors.
jbritton 12 hours ago [-]
I thought you corrected gamma in the monitor settings, not in your application code. Am I wrong.
blt 15 hours ago [-]
I wonder why we use something polynomial-based instead of something exponential-based like the decibel scale?
mianos 14 hours ago [-]
A power function seamlessly maps 0 to 0 and 1 to 1, easy for black to white.
An exponential/log function requires arbitrary clamping or offsets because you cannot represent pure black, 0, on a pure log scale without hitting negative infinity.
Basically, it fits better, aside from a good map of human perception
LoganDark 17 hours ago [-]
> Pixels with RGB values of (128, 128, 128) emit about half as much light as pixels with RGB values of (255, 255, 255).
Technically, this is not always incorrect, if your working color space is linear and 0 is no light. The problem only comes if you hand that same data to routines or surfaces expecting sRGB or another nonlinear color space (or one where 0 is not no light).
nomel 17 hours ago [-]
> or one where 0 is not no light
Oh, interesting. What's an example of this? Some sort of log space?
Someone 16 hours ago [-]
I would think the color spaces of most displays have that, don’t they?
The bevel of a black iPhone is darker than its screen, even when powered off. Similarly, switched off CRT displays aren’t truly black.
15 hours ago [-]
LoganDark 8 hours ago [-]
That isn't light emission, though.
account42 2 hours ago [-]
Doesn't really matter if the light is emitted or reflected, it still affects your perception.
LoganDark 2 hours ago [-]
Perceptual color accuracy is usually handled at the display manager or operating system level; wherever monitor color calibration is applied. You don't usually have to worry about it, unless your target audience puts you especially in charge of it. (Certain applications on Windows and Linux do this for color-grading workflows.)
LoganDark 17 hours ago [-]
Oh, I was just listing the constraints. I'm not directly aware of a color space where value 0 is not no light. It would however mean that even if linear, doubling a value relative to 0 wouldn't necessarily double the amount of light.
pavlov 17 hours ago [-]
Most video color spaces have black at a non-zero code value.
The most common 8-bit YUV format (e.g. in MPEG-2) uses a 16-235 range for valid luma values, so black is at 16 and white is at 235.
The reason for leaving this “headroom” and “footroom” had to do both with digitizing analog signals and avoiding clipping during processing.
nicebyte 15 hours ago [-]
there isn't much that is "arcane" about gamma correction itself (as in, the math itself is really simple).
at the fundamental level, if a surface is illuminated with one lightbulb and we add another light bulb, the difference is exteremely noticeable to the human eye. if we add one more lightbulb to a surface that is already illuminated by a hundred light bulbs, there will be no perceptible difference. the exact response can be modeled with a pretty simple power law (with a modification in the low range, as the article mentions).
that's all there really is to "gamma correction". it's a hack that exploits this quirk of the human visual system in order to more efficiently allocate bits for encoding different "lightness" values.
all of the confusion and bugs stem from one or more of the systems in the chain that forms the final image, making an incorrect assumption about what the others are doing. it's a bit like coordinate spaces in that regard.
nicebyte 15 hours ago [-]
general rule of thumb is that you never want gamma-corrected values if you intend to be doing any sort of math with them. the only exception is when you want to match the behavior of softwares that actually do all the math with pixel values in sRGB space (I think that's what photoshop does but don't quote me on that).
>The transformation used to represent the physically linear intensity data either generated synthetically via an algorithm or captured by a linear device (such as a CMOS of a digital camera or a scanner) with the discrete values of the perceptually linear scale is called gamma encoding.
This isn't super correct, and it underscores the biggest issue in this article:
sRGB (and its gamma encoding function) has absolutely nothing to do with perceptual linearity. sRGB is not perceptually linear! The original gamma encoding as far as I'm aware was made to compensate for the nonlinear transfer function of CRTs back in ye olde days. Its true that human vision is nonlinear, but sRGB is not a particularly good match to the perceptual linearity of human vision. Its a really common error to make, and leads to people wondering why we can't use sRGB to blend in if the reason why it was invented is because its perceptually linear
The article goes to compound on this mistake, which is why this is such a problematic misconception:
> Interestingly, Photoshop antialiases text using γ=1.42 by default, and this indeed seems to yield the best looking results (middle image). The reason for this is that most fonts have been designed for gamma-incorrect font rasterizers, hence if you use linear space (correctly), then the fonts will look thinner than they should.
This is where the mistakes start to add up
Consider what you're trying to achieve during antialiasing: when rasterising a line, lets say we discover that a pixel is only 40% covered and want to darken it. This means that we want our pixel's brightness to decrease by 40% to a human being. We don't want to emit 40% less light, because that's not what antialiasing is trying to achieve!
Both sRGB and linear colour are the wrong colour spaces to use. You want to blend in a perceptually linear colourspace, and photoshop's 1.42 gamma exponent probably maps better to human vision than 2.2 or 1.0 while being cheaper than a LUV conversion
>The standard gamma (γ) value to use in computer display systems is 2.2. The main reason for this is because a gamma of 2.2 approximately matches the power law sensitivity of human vision
The gamma transfer functions are also wrong. Its worth getting hung up on because it actually causes nontrivial errors, especially in the age of hardware accelerated sRGB conversions where doing it correctly is free
When doing a smooth fade-to-black in video, you may want to gradually decrease the amount of emitted light from the whole frame in a way that is smooth to a human. Here I think you should consider how a perceptual space can help.
The antialiasing value you get represents how much the pixel is covered by the glyph in question, and directly represents a desired change in perceptual brightness. There's no physical underlying lighting process, so it doesn't make sense to use physical light units
Blending in linear RGB models different strength lights being mixed together. This is why you do want to blend images together in linear RGB, but not fonts - because its not an underlying light based transport process
To take a direct example: Imagine two cases
1. We blend a white font on a black background
2. We blend a black font on a white background
Using perceptual blending, the antialiasing will be exactly the same efficacy in both cases. Using blending in linear space, these two test cases will look very different and render incorrectly!
The reason why gamma has been preserved in digital television even after CRTs have become obsolete is that it happens to perform a dynamic range compression that allows the use of 8 bits for luminance or for color components without making too visible the steps between adjacent color values.
If you want to encode the color components linearly, you need to use more than 8 bits, preferably the FP16 format, which was originally introduced in GPUs especially for this purpose.
So today the only purpose of gamma is as a method of data size compression that is specific to images, by allowing the reduction of the number of bits per pixel, while keeping acceptable the degradation of the image quality.
It is probable that the standard gamma curves are not optimal for data compression, but the slight improvements in image quality that could have been attained with other curves are not worth the complications that would have been created by abandoning the compatibility with legacy recordings.
Even within "SDR"/"sRGB", many mistakes crop up from people erroneously mixing content encoded with the piecewise sRGB transfer function with content encoded according to a plain gamma 2.2 transfer function. And this is before we are getting into e.g., incorrect blending spaces or mismatched primaries.
But yes, it is purely a matter of compression, with many options for exactly what dynamic range you need and how you want your content defined (e.g., sRGB, gamma2.2, scRGB, HLG, PQ, ...), with linear light primarily reserved as an intermediate space for color conversions and blending - something your display server and any software working with arbitrary color spaces will be using.
Such differences in standards already existed in analog television, because, depending on how they were made, the CRTs also had slightly different transfer curves from grid voltage (where the video signal was applied) to anode current (which is proportional with the luminance of the pixel component), and the regional TV standards accounted for the dominant manufacturers of the CRTs sold in that region.
https://www.youtube.com/watch?v=LKnqECcg6Gw
This is why when these older games crashed on your PC, the monitor would look all washed out due to the manual gamma adjustments the game made that didn't get restored.
The gradient examples between high-chroma colors of similar luminance are highly misleading in my opinion. In that particular case, linear just happens to do well (and device RGB of course poorly), but in other cases linear is not great. For example, blue to white is especially bad, with hue shifts as well as lightness non-uniformity.
You can experiment with this in the interactive tester in my Oklab review[1].
[1]: https://raphlinus.github.io/color/2021/01/18/oklab-critique....
What every coder should know about gamma (2016) - https://news.ycombinator.com/item?id=27721094 - July 2021 (50 comments)
What every coder should know about gamma - https://news.ycombinator.com/item?id=12552094 - Sept 2016 (183 comments)
It's interesting how this part of the trade-off changes when using float16 for color components (as is common when HDR is involved) rather uint8.
Good timing that Safari 27 adds support for srgb-linear and display-p3-linear color spaces.
I felt the first one looked more even. On the first I could tell the difference between every two adjacent bars. On the second one I couldn't tell any difference between the first 4-5 bars.
An exponential/log function requires arbitrary clamping or offsets because you cannot represent pure black, 0, on a pure log scale without hitting negative infinity.
Basically, it fits better, aside from a good map of human perception
Technically, this is not always incorrect, if your working color space is linear and 0 is no light. The problem only comes if you hand that same data to routines or surfaces expecting sRGB or another nonlinear color space (or one where 0 is not no light).
Oh, interesting. What's an example of this? Some sort of log space?
The bevel of a black iPhone is darker than its screen, even when powered off. Similarly, switched off CRT displays aren’t truly black.
The most common 8-bit YUV format (e.g. in MPEG-2) uses a 16-235 range for valid luma values, so black is at 16 and white is at 235.
The reason for leaving this “headroom” and “footroom” had to do both with digitizing analog signals and avoiding clipping during processing.
at the fundamental level, if a surface is illuminated with one lightbulb and we add another light bulb, the difference is exteremely noticeable to the human eye. if we add one more lightbulb to a surface that is already illuminated by a hundred light bulbs, there will be no perceptible difference. the exact response can be modeled with a pretty simple power law (with a modification in the low range, as the article mentions).
that's all there really is to "gamma correction". it's a hack that exploits this quirk of the human visual system in order to more efficiently allocate bits for encoding different "lightness" values.
all of the confusion and bugs stem from one or more of the systems in the chain that forms the final image, making an incorrect assumption about what the others are doing. it's a bit like coordinate spaces in that regard.