Using colors

In games, you might have seen many kinds of graphical effects, such as screen desaturation, HDR image enhancing, or hue shifting. All these effects use the principle of converting between color models to another color representation, which allows you to easily change certain aspects of drawing things on screen. This recipe will try to explain how to convert between color models and how to use them in further image processing.

Usually, colors are defined by three color components—red, green, and blue. This color representation is also known as RGB. There are more methods to define a color. These methods are also called color models. They describe that each one is used in different situations. For example, the RGB color model uses additive color mixing. This is because computer displays use these three colored lights to mix the final color you can see on the screen. Printers use the CMYK color model, which uses subtractive color mixing. This is based on mixing colors like when you are painting on paper. Color mixing on paper behaves differently to mixing colored lights. However, there are many more color models. HSL or HSV color models can be used to a color in terms of hue, saturation, and lightness, or a value. These color models allow you to easily change the color saturation or any other color parameter.

Note that graphic cards use internally RGB color models and it's commonly extended with alpha channels to define the transparency. However, in the end, the result in the GPU framebuffer always uses RGB triplets for colors.

Another point to mention is that color conversion is exact between the RGB and HSL color models, whereas conversion between RGB and CMYK is not so precise. This is because HSL is just another color representation developed for computer graphics applications to make color handling simpler. In contrast to that, the CMYK color model is bound to color mixing processes in printers. While colors on computer display produce the light, colors on a sheet of paper adjust the reflected light to the perceiver. The color representation on a paper is dependent on the paper material, surrounding light and a halftone rasterizing method. These facts can help you with the choice of color model for your situation.

Getting ready

This recipe will show you how to convert between the three most commonly used color models. The methods that are described here can be used inside your application, for example, for color picking and as a part of your fragment shader code, where you can adjust color rendering on screen—color desaturation.

How to do it…

The most common color models used in games are RGB, HSL, and CMYK. The first part of this recipe will deal with conversions between the RGB and HSL color models. The second part will cover conversions between RGB and CMYK color models. RGB color models play a central role as they are used internally in graphic cards:

  1. Converting a color from HSL to RGB;
    function hsl2rgb(h, s, l)
      local r, g, b
      if s == 0 then
        r,g,b = l,l,l -- achromatic
      else
        local p, q
        local function hue2rgb(t)
          t = math.fmod(t, 1)
          if t < 1/6 then
            return p + (q - p) * 6 * t
          elseif t < 1/2 then
            return q
          elseif t < 2/3 then
            return p + (q - p) * (2/3 - t) * 6
          else
            return p
          end
        end
        if l < 0.5 then
          q = l * (1 + s)
        else
          q = l + s - l * s
        end
        p = 2 * l - q
        r = hue2rgb(h + 1/3)
        g = hue2rgb(h)
        b = hue2rgb(h - 1/3)
      end
      return r, g, b
    end
  2. Converting a color from RGB to HSL:
    function rgb2hsl(r, g, b)
      local max = math.max(r, g, b)
      local min = math.min(r, g, b)
      local h,s, l = (max + min) / 2 -- luminance
      s, l = h, h
      if max == min then
        h,s = 0,0 -- achromatic
      else
        local d = max - min;
        if l > 0.5 then
          s = d / (2 - max - min)
        else
          s = d / (max + min)
        end
        if max == r then
          if g < b then
            h = (g - b) / d + 6
          else
            h = (g - b) / d + 0
          end
        elseif max == g then
          h = (b - r) / d + 2
        elseif max == b then
          h = (r - g) / d + 4
        end
        h = h / 6
      end
      return h, s, l
    end
  3. Converting a color from CMYK to RGB:
    function cmyk2rgb(c, m, y, k)
      local r, g, b
      r = 1.0 - (c * (1.0 - k) + k)
      g = 1.0 - (m * (1.0 - k) + k)
      b = 1.0 - (y * (1.0 - k) + k)
      return r, g, b
    end
  4. Converting a color from RGB to CMYK:
    function rgb2cmyk(r, g, b)
      local c, m, y, k
      if (r == 0) and (g == 0) and (b == 0) then
        c, m, y, k = 0, 0, 0, 1
      elseif (r == 1) and (g == 1) and (b == 1) then
        c, m, y, k = 0, 0, 0, 0
      else
        c = 1.0 - r
        m = 1.0 - g
        y = 1.0 - b
        local minK = math.min(r, g, b)
        c = (c - minK) / (1.0 - minK)
        m = (m - minK) / (1.0 - minK)
        y = (y - minK) / (1.0 - minK)
        k = minK
      end
      return c, y, m, k
    end

How it works…

In the case of converting the HSL color model into RGB, the algorithm first tries to determine whether the color is achromatic. This means saturation is 0 and so there's no point in computing hue. Such computation is quickly over because the resulting RGB color is computed only with lightness. If the saturation is greater than zero, the hue2rgb function is used to determine a linear combination of the R, G, and B color channels. The following figure shows how the color channels are combined:

How it works…

The P and Q quotients are dependent on lightness and saturation and they form the final values of the R, G and B channels.

Conversion from RGB to the HSL color models starts with finding what color channel has the greatest (maximum) and lowest (minimum) value. The next thing is the lightness value, which you can derive by getting the mean value or the minimum and maximum values. If the minimum and maximum values are equal, it means that the color is achromatic—zero color saturation. Otherwise, there is a saturation which you can get by using the following formula:

if lightness <= 0.5 then saturation := (max-min)/(max+min)
if lightness > 0.5 then saturation := (max-min)/(2-max-min)

Now you're left with computing the hue. You can refer to the previous figure to see the relation between the color channel with the maximum value and the position on the hue palette. The color spectrum can be divided into six parts, where the maximum channels are paired next to each other, except the red channel. If the red color is the maximum, you'll be looking either on the left or on the right side of the spectrum. You can get a finer position by getting the parameter of the linear combination of the other channels. The generalized formula will look like this:

h = N + (B - A)/(max - min)

Here, N would be the part of sextant, B would be the rising channel on the right, and A would be the falling channel on the left. The value of the finer position is in the range of (-1,1). The final value of the hue can be obtained by dividing the hue by 6, which will map the value into the range of (0,1).

CMYK to RGB color model conversion uses a set of formulas, which are as follows:

  • R = (1-C)*(1-K)
  • G = (1-M)*(1-K)
  • B = (1-Y)*(1-K)

Note that CMYK uses subtractive color mixing. Therefore, the red color is mixed from the negative color of cyan, the green color is mixed from the negative color of magenta, and the blue color is mixed from the negative color of yellow.

The RGB to CMYK formula is a bit more complicated and is listed as follows:

  • K = 1 - Max(R, G, B)
  • C = (1 - R - K)/(1 - K)
  • M = (1 - G - K)/(1 - K)
  • Y = (1 - B - K)/(1 - K)

All color models mentioned in this recipe work with the channel range of (0,1).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.108.119