I have a texture and I want to "colorize" it with a given color, lets say cyan (#00ffff) or purple (#800080). What I want to do, is get all the pixel values from the texture, and remove the color and keep the "brightness" and "saturation" and apply to the desired color. There is a tool in GIMP to do this called Colorize (Colors -> Colorize.. while editing), I made an example below.

This is will all be done in a shader (GLSL), although this is probably a general algorithm.

enter image description here


This live demo uses the algorithm described by @Dries in a fragment shader to colorize the incoming fragment color.

It basically can be summarised by:

vec4 getInputColor()
    TODO: sample from a texture / use a uniform var / varying ...

vec4 toGrayscale(in vec4 color)
  float average = (color.r + color.g + color.b) / 3.0;
  return vec4(average, average, average, 1.0);

vec4 colorize(in vec4 grayscale, in vec4 color)
    return (grayscale * color);

void main()
  // This is the color you want to apply
  // in the "colorize" step. Should ultimately be a uniform var.
  vec4 c = vec4(0.0, 1.0, 1.0, 1.0);

  // The input fragment color.
  // Can come from a texture, a varying or a constant.
  vec4 inputColor = getInputColor();

  // Convert to grayscale first:
  vec4 grayscale = toGrayscale(inputColor);

  // Then "colorize" by simply multiplying the grayscale
  // with the desired color.
  vec4 colorizedOutput = colorize(grayscale, c);

  // Done!
  gl_FragColor = colorizedOutput;
  • \$\begingroup\$ This would be better as a comment, since without the link, it's a very vague answer. \$\endgroup\$ – MichaelHouse May 31 '14 at 22:04
  • \$\begingroup\$ @Byte56 Without the link? \$\endgroup\$ – glampert May 31 '14 at 22:06
  • 2
    \$\begingroup\$ Yes. In the future, if the link were to no longer point to anything, this answer would be no good. \$\endgroup\$ – MichaelHouse May 31 '14 at 22:44
  • \$\begingroup\$ Why, the only way it can happen is if the website goes offline, and this can happen even with Wikipedia. I'm pretty sure the shader source is encoded in the URL, so it doesn't have an expiration date. But to be sure, I'll post a code snippet here then... \$\endgroup\$ – glampert May 31 '14 at 23:20
  • 1
    \$\begingroup\$ Note that this answer will not produce the results as shown in the question. White will also become the color you want to colorize with, but in the question white is preserved. My guess is that the correct answer would have to convert the color to hsl and then only adjust the hue, but leave saturation and lightness intact. \$\endgroup\$ – Adion Feb 12 '17 at 8:29

If you want it exactly like the thing above you'll first have to make your render grayscale.

You can do this in the pixel shader by taking a sample of the texture you were using (or only the color doesn't matter). Make a sum of the r, g and b value and divide that by 3. Return that value as the rgb values from the pixel shader.

Then do this (with or without the grayscale). Multiply the color of your texture (or the value of the grayscale) with the color you want.

Return that value in your pixel shader and that should be it.


If you just multiply a grayscale with a color, white will become that color instead of staying white. Instead, multiply only for gray values up to 0.5 and for brighter values, mix the color with white (the mix value will be the gray value normalized from [0.5..1.0] to [0.0..1.0]. So the mix amount would be (grayVal-0.5)*2.0

  • \$\begingroup\$ Adding (pseudo) code and/or name (if exist) of mix algorithm would greatly improve the answer. \$\endgroup\$ – wondra Apr 19 '18 at 19:25
  • \$\begingroup\$ @wondra "mix" is the name OpenGL uses for "lerp" so mix(a, b, t) = (1 - t) * a + t * b \$\endgroup\$ – DMGregory Apr 19 '18 at 19:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.