Here's the shocking truth: actually, this is not possible. You can't obtain all visible colors by mixing only three colors ( or four, or more for what matters ).
It is true, however, that red, green an blue mixed together capture all visible “chromes” you can see. That is, any color you can name, like “yellow”, “violet”, “pink”, can be made out of those three.
However, even if you choose accurately the red, green and blue to mix, you will not be able to make a very sarurated orange, or violet, or pink for example, despite the fact that your eye can see that color without problems, so it’s still a visible color.
Wait, what? How do computers show every possible color by emitting usually a red, blue and green light then?
In fact, they don't! Displays can only emit a pretty wide range of what you can see, but it would be a lie to say "all colors". The reason for this, is that almost every modern display adopts the sRGB color space, and they can only display colors that are in that space.
To understand what this sRGB is all about, let's start with eye and human color reception.
|Wavelengths of visible light|
Light is an electromagnetic wave and, as such, it propagates with a wave length, frequency and amplitude. The human eye is able to "capture" light with a wave length from approximately 390 to 700 nano-meters, which is what we perceive as "visible light". Light outside that range is not visible to our eye and gets those fancy names such as "infra-red", "ultra-violet", "micro-waves", "x-rays", etc.
This "invisible light" is used in countless occasions, from medical usage, wireless communications to warming up food in a microwave oven.
So how does the human eye "capture" the visible light we are interested in? It does so by using many "groups" of cones, each of them containing exactly three cones, which are stimulated by light in three different ways: One is particurlary sensible to high frequency light (blue), the second to middle frequency (green), and the third to low frequency (red). Aha! So our eye does use three receptors (a tristimulus) to capture light, so by using at least three colors for our monitors maybe we are on the right track.
Unfortunately, it is not as simple as that... .
Remember, I said they are “particularly” sensible to that light, not “only”. In fact, if we take a look at the response curve of each cone, we can see that actually they greatly overlap:
|Sensitivity (Y axis) of each cone for each wavelenght (X axis)|
What this means, is that it just doesn't exist a certain color (a certain wave length) which stimulates only one of those cones. Looking at the graph, this means finding a value for X in which only one curve is greater than zero. To make matters worse, light of a single wavelength ( also called pure monochromatic light ) does not exist in nature for physical reasons, so a ray of light will be always a mix of frequencies. (Even lasers which are close to emitting a single wavelength, cannot emit exactly one)
Tests have been conducted to represent, mathematically, all visible colors, and it has been found that they can be expressed with three mathematical coordinates, XYZ. Each of these coordinates costitutes the intensity of an “imaginary color”, a color with a wavelength that does not exist and is hypothetical. These three “imaginary colors” combined together can make any possible color, and this time for real!
As we are dealing with three quantities here, you can guess we can express them in an XYZ Cartesian cube. However only a part of this cube is made of actually visible colors.
To more conveniently visualize visible colors, these three coordinates are further transformed, and a XY graph (ignoring Z) looks like this:
|Visible color gamut|
The third coordinate, Z, changes the overall brightness of the colors you see in the above graph.
So, as you can see, all visible colors together form a toungue-like shape, and this is called the “color gamut”.
Interesting... but, wait a second, how can we see all visible colors in this image on our monitor to begin with, if we just said monitors cannot display all colors?
Yes, we are cheating here. The image uses only colors your display can show, but in reality part of that shape is made up of colors your monitor is unable to reproduce.
However the real usefulness of this XY representation is that it enables us to tell which part of the visible colors three chosen primary ones can reproduce. This is as simple as connecting them to form a triangle on the gamut, what’s inside the triangle is what you can reproduce.
Now finally we can take a look at how does the "sRGB" triangle looks like:
|sRGB color gamut|
As you can see, sRGB does a pretty good job including most of the reds but fails to reproduce colors especially towards a saturated green. You may be wondering, why not choose a primary colors which are nearer to the edges or, ideally, on the edges to include more colors? One reason for this is cost, producing phoshors for monitors which morereproduce colors near edges is expensive. The other reason lies on the fact that we have a limited number of bits to express colors, so a wider gamut doesn't necessarily mean a better appearence since the bigger the gamut, more "spread out" reproducible colors will be.
sRGB is a very good compromise of cost and appearance, and thus is widely used. There are however other color spaces such as "AdobeRGB" which have a wider gamut, meant especially for photography and printing. There are even color spaces which have four primary colors instead of three to form a quadrilateral, but most often the benefits don't out weight costs.
Now that we understood what colors are inside the sRGB color space and which primary colors are chosen as R, G, and B, we need a way to identify the intensities of each of those using numbers, so that we can store them in a computer. If we call "0" the minimum intensity and "1" the maximum intensity, and the other intensities are in between, the most straightforward way is to express that as-it-is in a number from 0.0 to 1.0. *
This is what is often called "linear sRGB", because it is sRGB with a linear transfer function (linear conversion from numbers to light intensities). Often it is referred as simply "RGB".
However, the original transfer function for sRGB is not linear. We will see the reasons why it is not, how that impacts the image, and why you should be aware of it while using OpenGL, or even tools like Unity while making games, explained in the next post!
* In OpenGL, for example, RGB8 texture format uses one byte per primary color, which means 256 different intensities for each and a total of roughly 16 million possible combinations.