# GLSL to tint greyscale image to color

My goal is to create a GLSL shader that will allow tinting of a greyscale image from 1 color to another color, depending on the range of an input from 0-1.
and also this related OpenGL question on Stackoverflow iphone - OpenGL ES 1.1: How to change texture color without losing luminance? - Stack Overflow

but am still stumped.
Can anyone point me in the right direction or get me started?

@art3mis

Multiplication is an easy way to do this if youâ€™re working with a gray scale image.
The first step for us to think about is the math thatâ€™s going to drive this operation.

Your first exploration here might be with multiplication. Thinking this way, the value of a given pixel will determine how strong the color comes through.

If our original pixel has gray value of (0.1, 0.1, 0.1, 1.0) we could just multiply that by our desired color (1.0, 0.0. 0.0, 1.0). The result would be (0.1, 0.0, 0.0, 1.0)â€¦ written another way:

(0.1, 0.1, 0.1, 1.0) x (1.0, 0.0. 0.0, 1.0) = (0.1, 0.0, 0.0, 1.0)

Thatâ€™s a kind of tinting - maybe not totally what youâ€™re after, but letâ€™s move that to a shader so you can see it in action.

A movie file in TOP connected to a monochrome top will get you a gray scale image to start with. From there we can connect this out a glsl TOP:

Next we can edit the shader code to start to get a result.

We need to start by declaring our new uniform:

``````// our new code is here
uniform vec3 uTintColor;

out vec4 fragColor;
void main()
{
// vec4 color = texture(sTD2DInputs[0], vUV.st);
vec4 color = vec4(1.0);
fragColor = TDOutputSwizzle(color);
}
``````

Next we need to change how our shader is working. We want to use the incoming color of our texture, so weâ€™ll un-comment the first line inside of `main()` so we have a gray scale value to reference. Weâ€™ll also get rid of the second color declaration:

``````// Example Pixel Shader

// uniform float exampleUniform;

// our new code is here
uniform vec3 uTintColor1;

out vec4 fragColor;
void main()
{
vec4 color = texture(sTD2DInputs[0], vUV.st);
fragColor = TDOutputSwizzle(color);
}
``````

What you should have now is this:

To implement the our first example letâ€™s make a few changes to our shader:

``````// Example Pixel Shader

// uniform float exampleUniform;

// our new code is here
uniform vec3 uTintColor1;

out vec4 fragColor;
void main()
{
vec4 color = texture(sTD2DInputs[0], vUV.st);
color.rgb *= uTintColor1;
fragColor = TDOutputSwizzle(color);
}
``````

All weâ€™ve done so far is multiply our pixelâ€™s value by that new uniform. What you should now have is:

Letâ€™s now add a second uniform thatâ€™s our second color:

``````// our new code is here
uniform vec3 uTintColor1;
uniform vec3 uTintColor2;

out vec4 fragColor;
void main()
{
vec4 color = texture(sTD2DInputs[0], vUV.st);
color.rgb *= uTintColor1;
fragColor = TDOutputSwizzle(color);
}
``````

Now we have a problemâ€¦ we could do something similar to our first step, but that wonâ€™t let us mix between these colors. Instead, letâ€™s declare two new variables that will hold our color information for us:

``````// our new code is here
uniform vec3 uTintColor1;
uniform vec3 uTintColor2;

out vec4 fragColor;
void main()
{
vec4 color = texture(sTD2DInputs[0], vUV.st);
vec3 col1 	= color.rgb * uTintColor1;
vec3 col2 	= color.rgb * uTintColor2;
color.rgb *= uTintColor1;
fragColor = TDOutputSwizzle(color);
}
``````

This is great, but we still need a way to mix between those two colors. Letâ€™s add another uniform:

``````// our new code is here
uniform vec3 uTintColor1;
uniform vec3 uTintColor2;
uniform float uMix;

out vec4 fragColor;
void main()
{
vec4 color = texture(sTD2DInputs[0], vUV.st);
vec3 col1 	= color.rgb * uTintColor1;
vec3 col2 	= color.rgb * uTintColor2;
color.rgb *= uTintColor1;
fragColor = TDOutputSwizzle(color);
}
``````

Finally, letâ€™s use this new variable to mix between color1 and color2:

``````// our new code is here
uniform vec3 uTintColor1;
uniform vec3 uTintColor2;
uniform float uMix;

out vec4 fragColor;
void main()
{
vec4 color = texture(sTD2DInputs[0], vUV.st);
vec3 col1 	= color.rgb * uTintColor1;
vec3 col2 	= color.rgb * uTintColor2;
color.rgb = mix(col1, col2, uMix);
fragColor = TDOutputSwizzle(color);
}
``````

Weâ€™re now mixing between these two tints based on the value of the uniform uMix:

Animated that should look like this:

Is that enough to get you moving? GLSL is a strange animal to get a handle of - the more you experiment the more it will make sense.

1 Like

Thatâ€™s awesome Matthew. Very much appreciated.