When you’re programming graphics, you’ll be dealing with color blending and pixels and bitmaps and images and pointers and scanlines and compression, alladat jazz. If you’re not fully trained, it could get quite overwhelming. If you want a super simplified explanation of graphics, it’s just a HUGE array of numbers. And an array itself is like a container, a piece of memory in your computer that stores all those numbers.
And depending on the bit-depth of colors you want to deal with, the more complex it’s all going to get. A bit depth is just the precision of colors that your computer might be able to represent in real life optically. It doesn’t matter most of the time if we cannot actually see the colors because a computer can actually simulate infinite possibility of colors virtually.
So an 8-bit depth color output will have less colors than a 16-bit or 24-bit or 32-bit color output. Therefore a higher color bit depth produces more colors represented in the real world.
Typically when you’re dealing with 32-bit colors in modern graphics programming, you’re working with a quadruplet of pairs of numbers like this:
RR stands for the hexadecimal number for red, GG stand for green, BB stands for blue, and AA stands for alpha value. A hexadecimal number is usually represented with alphanumerical values ranging from 00 to FF, in binary terms, numerical values ranging from 0 to 255. Converting hexadecimal code into binary into human readable numbers can get quite complex, so I’m just going to skip that explanation. Y’all script kiddies can go dig that headache up for yourselves.
//Here's an example of how to represent the color red FF0000FF //red == FF == 255, green = 0, blue = 0, alpha = 255 or 255,0,0,255
Note though the order of each color element varies across many drawing systems, so you have to make sure you’re using the right format. It could be like RRGGBBAA or AARRGGBB or BBGGRRAA or AABBGGRR, etc, etc.
Let’s say I want to make my red color darker. Since every color element is bound between values of 0 and 255, you get a total of 256 colors to play with, it includes the value 0, so pay attention, this might confuse some of you. 0 is complete black and 255 is complete white. So a value of 255 for the red component of a color will give you the “purest” value of red. Any value less than 255 is a darker value of red, one that is closer to black. Check this out:
//very dark red 100000FF or 16,0,0,255 //mid tone red 990000FF or 153,0,0,255
You can do this for each color element:
//very dark blue 000010FF or 0,0,16,255 //mid tone blue 000099FF or 0,0,153,255
But that might get boring and the fun comes when you start “blending” the basic colors RED, GREEN, AND BLUE together! Check this out:
//yellow = red + green FFFF00FF or 255,255,0,255 //magenta = red + blue FF00FFFF or 255,0,255,255 //orange = red + little less green FFAA00FF or 255,170,0,255
It helps if you memorize these combinations!
And look at how gray tones are created:
//gray tones are just the same value for every color component! //this would produce a slightly darker than middle gray 666666FF or 102,102,102,255 //a lighter gray EEEEEEFF or 238,238,238,255
Isn’t that neat and easy? Now let’s get to the alpha value. The alpha value isn’t required all the time because we assume we always want our colors opaque, even if its been blended with another color. The alpha value exists more out of convenience. It’s useful for applying a uniform change to every component of the color. Check this out:
//full opaque red 255,0,0,255 //50% translucent red, alpha = 128 because 128 is 50% of 255 255,0,0,128
So if you want to retain the translucency after blending two translucent colors, you’d do something like this:
//50% translucent red 255,0,0,128 //50% translucent blue 0,0,255,128 //combined result is 50% translucent dark magenta int rr = (255 + 0) / 2 //128 int gg = (0 + 0) / 2 //0 int bb = (0 + 255) / 2 //128 int aa = (128 + 128) / 2 //128 blendedColor = 128,0,128,128
When you change the alpha value, what you’re doing is changing the relative ratio of each color component to it’s initial values. You can think of it something like this:
//Say I want to set my color to 25% of it's initial value //use easy numbers here 100,50,75,255 //initial color values int rr = 100 * 0.25 //25 int gg = 50 * 0.25 //12.5 int bb = 75 * 0.25 //18.75 alphaChangedColor = 25,13,19,255 //Noticed the alpha value remains at 255 because we dont want to change the transparency 25,13,19,255 == 100,50,75,64 //whhhhuutttt????
That’s because the color values on the left has no translucency, it’s already blended with the background color, which is usually pure black, all zeros 0,0,0,0. The color values on the right retain the original color values but now can be blended with whatever background color values you want, or manipulated in other ways. See? It’s abstract math and problem solving! That’s why you had to pay attention in math class.
//here's more detailed math how it works //using proportions formula from math class a / A = x / X //you cross multiply these fractions to solve for any of the values //like this, if I was trying to solve for x a * X = A * x x = (a * X) / A //so if I wanted to make my color 25% less than its original values newValues / originalValues = 25 / 100 newValues * 100 = originalValues * 25 newValues = (originalValues * 25) / 100 //take each color component and find the proportional value
When you’re working with computer graphics and blending colors, the proportions math formula is going to be used a lot! You’re trying to find relativity of highlights and shadows, how color is casted or bounced, which is lighter or darker, which colors to draw and not draw, etc, all decisions you have to make but has to have some sound math behind it! All this stuff I just showed you is considered the basic stuff. So keep at it!