The fastest, easiest way to turn your programmer art into something people will actually want to look at is to get a handle on color. In this tutorial we’re going to learn how to think about color procedurally and use that knowledge to generate color schemes. Allow me to mention first that most of the information here is a simplification. The goal of this tutorial is not to provide a comprehensive explanation of how color is turned from a memory value to a stream of photons that enters your eyeball, and how your eyeball interprets those photons. It is instead to provide you with a working knowledge of how color is manipulated and displayed in computer systems. For that first thing, check out this incredible blog post by Jamie Wong.
Computer screens these days are made up of hundreds of thousands of pixels, which in turn are made of subpixels, which are tiny lights that emit some amount either red, green, or blue light. We use these colors because they roughly correspond to the sensitivities of the three types color-detecting cells in your eyes, called cones. Thus, the obvious way to store color values is to just store how much red, blue, and green light makes up each color. This is the idea behind the RGB color model, which is the de facto standard for storing color information on computers1. You can think of an image as just a file containing a list of numbers, with the first number representing the amount of red in the first pixel, the second representing the amount of blue in the first pixel, the third representing the amount of green in the first pixel, and so on for every pixel in the image. Real image formats are more complicated than this because of compression, but often this is how color data will be given to you by APIs designed to read and process image data. In an API, you'll often see these numbers as either a real number between 0 and 1, with 0 being no red/green/blue and 1 being maximum red/green/blue, or as an integer between 0 and 255 (the largest number that can be represented with eight binary digits, or one byte of data).
There are problems with the RGB color model, however (understatement of the century). The one that most immediately concerns this tutorial is that while it does a decent job of representing colors as screens display them, it bears very little relationship to how artists and color theorists actually discuss and categorize colors. RGB is what's called an additive color model, meaning that when all the component colors are at their maximum possibel value, white is produced. This is how light behaves -- white light is a combination of all colors of visible light in equal amounts. However, pigments don't work like this. combining red, green, and blue paint does not give you white paint, it gives you a brownish-black color. This is more like a subtractive color model, where all the colors combined give you black. The most common subtractive color model is the CMYK color model, which uses the constituent colors of Cyan, Magenta, Yellow, and Black.2.
However, the CMYK color model doesn't escape the more fundamental problem that we don't usually look at colors and describe them in terms of how red, blue and green they are, or in terms of how cyan, magenta, yellow, and black they are. For that, we can turn to another model, the one we'll be using for most of the rest of this tutorial: the HSV color model. HSV stands for "Hue Saturation Value", and you'll sometimes also see it called "Hue Saturation Lightness" (HSL), or "Hue Saturation Brightness" (HSB).3 HSV is what's called a "cylindrical" color model, as opposed to the cubic geometry of the RGB color model. H represent's the color in question's position on the color wheel, forming the circular top of the HSV cylinder. You can think of hue as a number of degrees around the color wheel, with 0 degrees being red, 120 degrees being green, 240 degrees being blue, and 360 degrees being red again, with the rest of the color wheel filling in the gaps. Sometimes this is represented by a number of degrees, but more often you'll see it like the parameters in an RGB color, either a real number between 0 and 1 or an integer between 0 and 255. Saturation can be thought of as the distance of the color from the center of the cylinder, or as the color's "paleness". Saturation is essentially a parameter that goes from completely white at 0 to being completely the hue at maximum value. Colors with saturations around 0 are often called "pastel colors". Value is similar, except it goes from completely black at 0 to completely the color (as modified by the saturation value) at maximum. This is kind of confusing to explain, but if you exammine the examples below it will probably make more sense.
So that's a lot of technical details about how computer programs represent color. How would you use this information to construct a good color scheme? Well, to do that, you're going to need to know some color theory. Color theory is a set of guidelines and descriptions for how humans perceive color. The most fundamental tool of color theory is the color wheel, a circular representation of the visible light spectrum, much like the hue value in the HSV color model. Colors opposite each other on the color wheel are called complementary colors. Complementary colors produce white (for additive color spaces) or black (for subtractive color spaces) when blended together. When placed next to each other, complementary colors provide the strongest possible contrast. In RGB, the complement of red is cyan: red is represented by the triplet (1, 0, 0), while cyan is (0, 1, 1): add those together and you get (1, 1, 1), which is white4.
Another commonly used concept in color theory is that of primary colors. We've already kind of covered this: the primary colors of a given color model are the colors that are combined to give you all the colors in the gamut, or set of possible colors in the space. The primary colors of RGB are, no surprise, red, green, and blue.
One other color theory concept that is useful to know is warm and cool colors. The warm colors are those bwetween red and yellow on the color wheel, usually also including brown. The cool colors are between blue-green and blue-violet, also including most grays. What constitutes a "warm" or "cool" color, and what effect that has on a viewer's perception of an image is a subject of considerable controversy. Broadly speaking, "warm" colors generally feel more active and exciting, while cool colors are passive and relaxing. There are also the obvious temperature associations: a scene containing mostly cool colors will usually be interpreted as being colder than one with mostly warm colors.
Let's put our knowledge together and imagine how we might write some code to generate different color schemes.
The most straighforward kind of color scheme is the monochrome color scheme. In a monochrome color scheme, you simply pick a color, and several different shades of that color.
numColors = 4 //how many colors we want our scheme to have colors =  //the final color palette array //get our hue first, outside of the loop, //so all the colors we make will have the same hue h = random(0, 1) for i = 0, numColors //all these colors are going to have the same saturation, //though you could experiment with changing this as well s = 1 //the value is going to go from 0 to 1 in steps //so that the last color will have 1 value, and the first color will be black. //you could instead multiply this by i + 1, //so that the darkest color will be a dark shade of your hue rather than black. v = (1/numColors) * i colors[i] = (h, s, v)
If you want to have more than one color, you could instead use a simple complementary color scheme. Complementary color schemes can be very harsh, and should probably be used sparingly.
colors =  h1 = random(0, 1) //pick a random hue // go halfway around the wheel of hues from the first hue. //use the modulo operator (%) to make sure that if the result // of (h1 + 0.5) is greater than 1 it wraps around. h2 = (h1 + 0.5) % 1 //here we're only storing the two fully saturated versions of our colors, //for a fuller color scheme you could do a similar loop to the //monochrome example to get some different shades of each color. colors = (h1, 1, 1) colors = (h2, 1, 1)
In a certain sense, the opposite of a complementary color scheme would be an analagous color scheme, where you pick colors (usually 3) that are right next to each other on the color wheel. You usually want to pick two colors to be your main ones and use the other one as an accent.
colors =  span = 0.125 // how wide a section of the color wheel we want to span h1 = random(0, 1) // pick a random hue h2 = (h1 + (span/2)) % 1 //go along the color wheel for half of the span h3 = (h1 - (span/2)) //go the opposite direction for half of the span //we can't use the modulo operator for negative numbers //because its behavior is poorly defined, so we have to check manually if h3 < 0 //"abs" means "absolute value", the total distance of a number //from zero (so abs(-3) == abs(3) == 3, for instance) h3 = 1 - (abs(h3) % 1) colors = (h1, 1, 1) colors = (h2, 1, 1) colors = (h3, 1, 1)
One common tactic for creating a color scheme is to pick colors evenly spaced around the color wheel. Generally speaking, with these sorts of color schemes, you want to pick one color as your main color and use the others as accents.
colors =  //triadic color scheme, four would be a tetradic square color scheme, //five would be a pentadic, etc numColors = 3 size = 1/numColors //get an offset so we don't get the same color scheme every time. //starting from a random h like we did before gives weird issues //where you get multiple of the same color offset = random(0, 1) for i = 0, numColors h = i * size //add the offset to the hue value then make sure it wraps around colors[i] = ((h + offset) % 1, 1, 1)
If the contrast of a straight complementary color scheme is too great, or if you simply desire more colors, you could go for a split-complementary scheme.
colors =  split = 0.125 h1 = random(0, 1) h2 = (((h1 + 0.5) % 1) + split) % 1 h3 = ((h1 + 0.5) % 1) - split if h3 < 0 h3 = 1 - (abs(h3) % 1) colors = (h1, 1, 1) colors = (h2, 1, 1) colors = (h3, 1, 1)
1. "RGB" is the blanket term for a large number of different RGB implementations, called RGB colors paces. These include sRGB, Apple RGB, Adobe RGB, and many others.
2. K is used instad of B for "black" because B is used to denote the color blue in the abbreivation "RGB". It's also worth noting that cyan is the color you get from an RGB triplet with maximum values for green and blue, magenta is the color you get from an RGB triplet with maximum values for red and blue, and yellow is the color you get from an RGB triplet with maximum values for red and green. Likewise, a CMYK quintuplet with maximum values for magenta and yellow will give you red, one with maximum values for cyan and yellow will give you green, and one with maximum values for cyan and magenta will give you blue.
3. Technically, these refer to slightly different things, but from the persepective of programming with them to generate color schemes, we can treat them as the same. I'll be using the term "HSV" for the rest of the article, because it's the precise color model I'm talking about, but often implementations will use "HSL" or "HSB" terminology whenthey really mean "HSV". Even more technically, HSV is not a color model in and of itself, but rather a way of representing the RGB color model that allows us to represent colors in the computer the way we usually talk about colors in reality.
4. Traditionally, painters have used the RYB color model, which is a subtractive color model like CMYK, but instead of cyan, magenta, and yellow, it uses red, yellow, and blue. In RYB, mixing red and green gives you black, and therefore red and green are complementary. Modern computer systems rarely if ever use the RYB color model, so you don't really have to worry about it, but people would get mad at me if I didn't mention it. Likewise, there's the opponent process theory of color vision, which is really complicated and not particularly relevant, but also agrees with RYB that the complement of red is green.