Advertisement

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

Started by May 16, 2019 07:16 AM
3 comments, last by cebugdev 5 years, 8 months ago

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?


image.png.acae943d0906cb7e29f0b0df08f98a83.png

S1.png

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. 

Advertisement

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);
}

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

 

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
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);
}

// In fragment shader...
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!

 

 

This topic is closed to new replies.

Advertisement