# OpenGL How to replace shade of color with a another color - GLSL/OGL

## Recommended Posts

Hi all,

How can i replace the shade of color to another color, on my attached image (S1.png), the image is of the shade of blue, and i want to replace the entire color with a different color

in GLSL but icannot just straight set the values as the colors are of different shade of blue.

What i am trying to achieve is this, the image represents something like a glow in the game and the color changes based on a certain type. Example is the other image attached (image.png), where  the blue color was replaced by red (dont mind the whitish color as i will overlay a white color on top of it).

How can i do this in shader part, whats the math or the things i need to research for this?

##### Share on other sites

If the only thing you are doing is replacing blue with red, all you need to do is to rewire the colors from your input color to your output color:

outputColor.r = inputColor.b
outputColor.g = inputColor.g
outputColor.b = inputColor.r

This should also take care of shades of blue and turn them to shades of red, as long as you only have shades of one color.

In general, if you start with an input color of (0,0,x), you need to put x in the right place in the output color. (x,0,0) for red, (x,x,0) for yellow and so on.

##### Share on other sites

And in the general case... create a metric for "how close are these two colours" in your colour space of choice (usually HSV is used for visual colour-matching), and use that value per-fragment to subtract the present colour and add the replacement colour.

// GLSL Pseudocode, do not copy/paste; re-type it.

float distance_metric(float3 a, float3 b) {
//TODO Re-interpret both as HSV (after this point, read "RGB" components as actually being "HSV" components instead).
// Calculate the distance in H, S, V spaces, apply tuning constants to suit your "tolerance" parameters.
float3 separation = (a - b).rgb * float3(rScale, gScale, bScale).rgb;
// Combine those axis separations into a linear distance, e.g. using pythagorus to get a meaningful scalar.
float dist = sqrt( separation.r * separation.r + separation.g * separation.g + separation.b * separation.b );
return clamp(dist, 0, 1);
}

uniform float3 old, new;
float match = 1.0 - distance_metric(fragment.rgb, old);
fragment.rgb -= match * old.rgb;
fragment.rgb += match * new.rgb;

##### Share on other sites
On 5/17/2019 at 12:25 AM, Wyrframe said:

And in the general case... create a metric for "how close are these two colours" in your colour space of choice (usually HSV is used for visual colour-matching), and use that value per-fragment to subtract the present colour and add the replacement colour.


// GLSL Pseudocode, do not copy/paste; re-type it.

float distance_metric(float3 a, float3 b) {
//TODO Re-interpret both as HSV (after this point, read "RGB" components as actually being "HSV" components instead).
// Calculate the distance in H, S, V spaces, apply tuning constants to suit your "tolerance" parameters.
float3 separation = (a - b).rgb * float3(rScale, gScale, bScale).rgb;
// Combine those axis separations into a linear distance, e.g. using pythagorus to get a meaningful scalar.
float dist = sqrt( separation.r * separation.r + separation.g * separation.g + separation.b * separation.b );
return clamp(dist, 0, 1);
}

uniform float3 old, new;
float match = 1.0 - distance_metric(fragment.rgb, old);
fragment.rgb -= match * old.rgb;
fragment.rgb += match * new.rgb;

wow, learning something new everyday, thanks man!

## Create an account

Register a new account

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 14
• 22
• 13
• 14
• 45