|
4 | 4 | //!
|
5 | 5 | //! # It's Never "Just RGB"
|
6 | 6 | //!
|
7 |
| -//! Colors in, for example, images are often "gamma corrected" or stored in |
8 |
| -//! sRGB format as a compression method and to prevent banding. This is also a |
9 |
| -//! bit of a legacy from the ages of the CRT monitors, where the output from |
10 |
| -//! the electron gun was nonlinear. The problem is that these formats doesn't |
11 |
| -//! represent the actual intensities, and the compression has to be reverted to |
12 |
| -//! make sure that any operations on the colors are accurate. This library uses |
13 |
| -//! a completely linear work flow, and comes with the tools for transitioning |
14 |
| -//! between linear and non-linear RGB. |
15 |
| -//! |
16 |
| -//! Adding to that, there are more than one kind of non-linear RGB. Ironically |
17 |
| -//! enough, this turns RGB into one of the most complex color spaces. |
| 7 | +//! Colors in, for example, images, are often "gamma corrected", or converted |
| 8 | +//! using some non-linear transfer function into a format like sRGB before being |
| 9 | +//! stored or displayed. This is done as a compression method and to prevent banding, |
| 10 | +//! and is also a bit of a legacy from the ages of the CRT monitors, where the |
| 11 | +//! output from the electron gun was nonlinear. The problem is that these formats |
| 12 | +//! are *non-linear color spaces*, which means that many operations that you may want |
| 13 | +//! to perform on colors (addition, subtraction, multiplication, linear interpolation, |
| 14 | +//! etc.) will work unexpectedly when performed in such a non-linear color space. As |
| 15 | +//! such, the compression has to be reverted to restore linearity and make sure that |
| 16 | +//! many operations on the colors are accurate. |
18 | 17 | //!
|
19 | 18 | //! For example, this does not work:
|
20 | 19 | //!
|
|
43 | 42 | //! .into_raw();
|
44 | 43 | //! ```
|
45 | 44 | //!
|
| 45 | +//! But, even when colors *are* 'linear', there is yet more to explore. |
| 46 | +//! |
| 47 | +//! The most common way that colors are defined, especially for computer |
| 48 | +//! storage, is in terms of so-called *tristimulus values*, meaning that |
| 49 | +//! all colors are defined as a vector of three values which may represent |
| 50 | +//! any color. The reason colors can generally be stored as only a three |
| 51 | +//! dimensional vector, and not an *n* dimensional one, where *n* is some |
| 52 | +//! number of possible frequencies of light, is because our eyes contain |
| 53 | +//! only three types of cones. Each of these cones have different sensitivity |
| 54 | +//! curves to different wavelengths of light, giving us three "dimensions" |
| 55 | +//! of sensitivity to color. These cones are often called the S, M, and L |
| 56 | +//! (for small, medium, and large) cones, and their sensitivity curves |
| 57 | +//! *roughly* position them as most sensitive to "red", "green", and "blue" |
| 58 | +//! parts of the spectrum. As such, we can choose only three values to |
| 59 | +//! represent any possible color that a human is able to see. An interesting |
| 60 | +//! consequence of this is that humans can see two different objects which |
| 61 | +//! are emitting *completely different actual light spectra* as the *exact |
| 62 | +//! same perceptual color* so long as those wavelengths, when transformed |
| 63 | +//! by the sensitivity curves of our cones, end up resulting in the same |
| 64 | +//! S, M, and L values sent to our brains. |
| 65 | +//! |
| 66 | +//! A **color space** (which simply refers to a set of standards by which |
| 67 | +//! we map a set of arbitrary values to real-world colors) which uses |
| 68 | +//! tristimulus values is often defined in terms of |
| 69 | +//! |
| 70 | +//! 1. Its **primaries** |
| 71 | +//! 2. Its **reference white** or **white point** |
| 72 | +//! |
| 73 | +//! The **primaries** together represent the total *gamut* (i.e. displayable |
| 74 | +//! range of colors) of that color space, while the **white point** defines |
| 75 | +//! which concrete tristimulus value corresponds to a real, physical white |
| 76 | +//! reflecting object being lit by a known light source and observed by the |
| 77 | +//! 'standard observer' (i.e. a standardized model of human color perception). |
| 78 | +//! |
| 79 | +//! The informal "RGB" color space is such a tristimulus color space, since |
| 80 | +//! it is defined by three values, but it is underspecified since we don't |
| 81 | +//! know which primaries are being used (i.e. how exactly are the canonical |
| 82 | +//! "red", "green", and "blue" defined?), nor its white point. In most cases, |
| 83 | +//! when people talk about "RGB" or "Linear RGB" colors, what they are |
| 84 | +//! *actually* talking about is the "Linear sRGB" color space, which uses the |
| 85 | +//! primaries and white point defined in the sRGB standard, but which *does |
| 86 | +//! not* have the (non-linear) sRGB *transfer function* applied. |
| 87 | +//! |
| 88 | +//! This library takes these things into account, and attempts to provide an |
| 89 | +//! interface which will let those who don't care so much about the intricacies |
| 90 | +//! of color still use colors correctly, while also allowing the advanced user |
| 91 | +//! a high degree of flexibility in how they use it. |
| 92 | +//! |
46 | 93 | //! # Transparency
|
47 | 94 | //!
|
48 | 95 | //! There are many cases where pixel transparency is important, but there are
|
|
0 commit comments