Interpolating between green and red...

Started by
8 comments, last by Sneftel 14 years, 5 months ago
I am creating a progress bar that I want to be some hue of green or red depending on its value. Currently I build a color map by linearly interpolating between green and red in RGB space. Here is some pseudo code illustrating my process:

int r = 0;
int g = 255;
int b = 0;

for(int i = 0; i < 255; ++i)
     colorMap = color(r+t, g-t, b);
I'm not pleased with the visual results. For example, the values in the middle are a muddy dark green. Are there any ideas on how I can achieve more "pleasing" results? Can I get more interesting results by using different color spaces?
Advertisement
You could split it into two different lerps. If between 0 and 50%, lerp from green into yellow. If between 50 and 100%, lerp from yellow into red. This should give more 'predictable' results ;)

You could also get more "intermediate" colour using another colour space, yes. E.g. lerp between red and green in HSL space, and then convert the result to RGB.
Interpolating RGB values usually ends up looking pretty horrible. But, you can interpolate HSL or HSV values easily with nice looking results. During render simple convert your values back into RGB and pass it to OpenGL.

Check it out: http://en.wikipedia.org/wiki/HSL_and_HSV

Google will give you a few simple functions to convert rgb to and from them, and once you have the conversion functions down its looks much nicer interpolating HSL/HSV's between each other.
Try Linear interpolation or Spherical interpolation

For linear interpolation:

DiffRed = ToRed - FromRed
NewRed = FromRed + (DiffRed * t)

t ranges from 0 to 1 use decimal for smooth gradient

Use the same for green and blue colors

In short you will have to define the initial color and the final color and interpolate between them using the t value.

Hope this helps.
From Logics To Lifehttp://bytelogik.wordpress.com
Second vote for "interpolate in HSL or HSV".
I've solved this problem in the past by doing gamma correction. Basically, a color number is not really proportional to the power emitted by the pixel.

power = color ^ gamma

Interpolating in power space should work well.

Color gamma_adjusted_interpolated_color(Color c1, Color c2, double t, double gamma) {  Power p1 = pow(c1, gamma);  Power p2 = pow(c2, gamma);  Power pi = (1.0-t)*c1 + t*c2;  return pow(pi, 1.0/gamma);}


Try with gamma values like 1.8 or 2.2 and see if you get what you want.
Do it a simpler way: texture ! (like in most artist control renderer)

Just draw a nice gradient from red to green with Photoshop, and use it as an input texture.
At runtime, just use your progress value as a texture coordinate to retrieve the correct color.
Some of my previous work on my personal webpage
Third vote for HSL.
Or if you want to keep it analytic, draw the gradient with Photoshop, then plot the intensity of each channel separately and by observing the values you'll get your equation.
Some of my previous work on my personal webpage
Just to be contrary: interpolate in sRGB. Won't be brightness-preserving, which I think is what you want, but it will lead to a perceptually linear response, as well as making at least a couple readers run to Wikipedia to learn about what sRGB is and why it matters to games.

EDIT: Actually, looks like alvaro mentioned gamma already, which is close to the same thing.

This topic is closed to new replies.

Advertisement