palette icon indicating copy to clipboard operation
palette copied to clipboard

Distinction between `Srgb` encoding and `Linear<Srgb>` encoding?

Open mitchmindtree opened this issue 6 years ago • 7 comments

Hi @Ogeon! I'm (finally) updating nannou from 0.2 to 0.4 and I'm a little confused about the distinction between the Srgb and Linear<Srgb> encodings.

I'd always thought that sRGB and Linear were two distinct encodings. Specifically, I thought that Linear was a direct mapping to the hardware output, whereas sRGB was a mapping that is friendlier to the perceivable colour range. What does it mean to have Linear<Srgb>?

Sorry for the ordinary question! Feel free to point me elsewhere if there's somewhere I can read up properly on this :pray:

mitchmindtree avatar Jun 19 '19 21:06 mitchmindtree

Hi! Excellent question and something that should be clarified in the documentation at some point.

The short version is that sRGB is basically a storage format, where the values does not map 1:1 with the intensity they represent. So 50% is not encoded as 0.5 in sRGB, and this will affect blending operations among other things.

Linear RGB is the "normal" scale, where 50% brightness is represented by 0.5, and the same goes for the rest of the scale. It's just straight intensity values (as far as that's true for RGB in general).

sRGB stems from how old CRT displays work and does also have the benefit of a higher resolution among the darker colors. That reduces the banding effect because it also matches how we see colors. It works as a type of compression.

This video explains it in a short and nice way: https://youtu.be/LKnqECcg6Gw

I would recommend a workflow or data flow where the color is converted to linear space as soon as possible and stays like that internally. It can then be converted back when it's outputted to some media that want sRGB (image, display, etc.). I.e. a "linear workflow".

Ogeon avatar Jun 20 '19 16:06 Ogeon

Thanks a lot for the valuable insight, I'm glad that I asked!

Is it possible for there to be other kinds of Linear<_> encodings? E.g. something like Rgb<Linear<Foo>, T> rather than Rgb<Linear<Srgb>, T>? I guess what I'm asking is, why does the Linear encoding type require specifying a <Srgb> type parameter if it is in a linear representation rather than an sRGB one?

I'll checkout this video tonight, I love minutephysics :)

mitchmindtree avatar Jun 20 '19 17:06 mitchmindtree

Yes! RGB has two other parameters, beside the "transfer function" (linear v.s. nonlinear):

  • The "primaries" decide what the physical definition (wavelength and light intensity) of "red", "green" and "blue" are.

  • The "white point" decides what the physical definition of "white" is. Basically the photon output of a light source.

There are plenty of RGB standards with different values for these, but sRGB is the most common. It's all a bit of a rabbit hole and you don't have to go down there unless you want to support working with a wider gamut (wider range of perceivable colors) or doing more advanced color adaptions.

Ogeon avatar Jun 20 '19 17:06 Ogeon

So Linear<Srgb> uses the primaries and white point of sRGB, but replaces the sRGB transfer function with the linear transfer function. The benefit of nesting the types is that ~~the conversion from linear will know what the original RGB standard was~~ we don't have to make purpose made linear versions of each standard (I remembered it wrong at first), as the RGB space is still the same.

Ogeon avatar Jun 20 '19 17:06 Ogeon

Thanks, that clears things up for me! I'm happy for this to be closed, but will leave it open in case you'd like the reminder for the addition to the docs :)

mitchmindtree avatar Jun 20 '19 17:06 mitchmindtree

It can stay open for now. 🙂 Feel free to come back and ask more if there are any more road blocks!

Ogeon avatar Jun 20 '19 17:06 Ogeon

Oh I should probably clarify that any shader code should also be considered being within the linear part of the pipeline, so don't convert to sRGB until just before it ends up on the monitor for the best results. That is unless the shader itself expect sRGB as input, or unless the graphics backed is set to convert it for you. I don't know how your current pipeline looks, so that may already be taken care of, but I'm mentioning it just in case...

Ogeon avatar Jun 20 '19 19:06 Ogeon