Sign in to follow this  
fpsgamer

Interpolating between green and red...

Recommended Posts

fpsgamer    856
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[i] = 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?

Share this post


Link to post
Share on other sites
Hodgman    51234
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.

Share this post


Link to post
Share on other sites
pto    194
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.

Share this post


Link to post
Share on other sites
bytelogik    108
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.

Share this post


Link to post
Share on other sites
alvaro    21246
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.

Share this post


Link to post
Share on other sites
Shirakana2    500
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.

Share this post


Link to post
Share on other sites
Shirakana2    500
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.

Share this post


Link to post
Share on other sites
Sneftel    1788
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this