Fun with color...
by Jason Cahill · in Torque Game Builder · 04/15/2006 (11:41 pm) · 3 replies
Hi everyone,
For my project I needed to be able to "tint" colors, based on existing colors. All of my sprites are pure white in the color channels and grayscale in the alpha channel. I then use .setBlendColor at runtime to color my sprites, based on player color or team color. I wanted the bullets from a given player object to be "of the same hue, but lighter and less saturated." So, here's the TorqueScript code to convert to and from RGBA (red-green-blue-alpha) to HLSA (hue-lightness-saturation-alpha):
For my project I needed to be able to "tint" colors, based on existing colors. All of my sprites are pure white in the color channels and grayscale in the alpha channel. I then use .setBlendColor at runtime to color my sprites, based on player color or team color. I wanted the bullets from a given player object to be "of the same hue, but lighter and less saturated." So, here's the TorqueScript code to convert to and from RGBA (red-green-blue-alpha) to HLSA (hue-lightness-saturation-alpha):
function Color::RGBA2HLSA(%rgba)
{
%r = getWord(%rgba, 0);
%g = getWord(%rgba, 1);
%b = getWord(%rgba, 2);
%a = getWord(%rgba, 3);
%max = ((%r > %g) ? ((%r > %b) ? %r : %b) : ((%g > %b) ? %g : %b));
%min = ((%r < %g) ? ((%r < %b) ? %r : %b) : ((%g < %b) ? %g : %b));
%l = (%max + %min) / 2;
if (%max == %min)
{
%s = 0;
%h = 0;
}
else
{
if (%l < 0.5) %s = (%max - %min) / (%max + %min);
else %s = (%max - %min) / (2 - %max - %min);
%delta = %max - %min;
if (%r == %max) %h = (%g - %b) / %delta;
else if (%g == %max) %h = 2 + (%b - %r) / %delta;
else if (%b == %max) %h = 4 + (%r - %g) / %delta;
%h *= 60;
if (%h < 0) %h += 360;
}
return %h SPC %l SPC %s SPC %a;
}
function Color::Value(%n1, %n2, %h)
{
while (%h > 360) %h -= 360;
while (%h < 0) %h += 360;
if (%h < 60) %v = %n1 + (%n2 - %n1) * %h / 60;
else if (%h < 180) %v = %n2;
else if (%h < 240) %v = %n1 + (%n2 - 1) * (240 - %h) / 60;
else %v = %n1;
return %v;
}
function Color::HLSA2RGBA(%hlsa)
{
%h = getWord(%hlsa, 0);
%l = getWord(%hlsa, 1);
%s = getWord(%hlsa, 2);
%a = getWord(%hlsa, 3);
if (%l <= 0.5) %m2 = %l * (1 + %s);
else %m2 = %l + %s - %l * %s;
%m1 = 2 * %l - %m2;
if (%s == 0)
{
if (%h == 0)
{
%r = %g = %b = %l;
}
else error("ERROR: HLSA2RGBA: hue must be 0 if saturation is 0!");
}
else
{
%r = Color::Value(%m1, %m2, %h + 120);
%g = Color::Value(%m1, %m2, %h);
%b = Color::Value(%m1, %m2, %h - 120);
}
return %r SPC %g SPC %b SPC %a;
}About the author
#2
HLS is not HSV. HSV is a cone, where as HLS is a double cone. "Pure colors", like pure red, green, blue, yellow, etc exist at lightness = 0.5. White is up at lightness 1, while black is at lightness 0. Saturation is "grayest" at 0 and "most chromatic" at 1. Hue goes from 0 to 360. Red is at 0, Green at 120, Blue at 240.
Enjoy!
04/15/2006 (11:51 pm)
Notes about HLS:HLS is not HSV. HSV is a cone, where as HLS is a double cone. "Pure colors", like pure red, green, blue, yellow, etc exist at lightness = 0.5. White is up at lightness 1, while black is at lightness 0. Saturation is "grayest" at 0 and "most chromatic" at 1. Hue goes from 0 to 360. Red is at 0, Green at 120, Blue at 240.
Enjoy!
#3
04/17/2006 (11:01 am)
Nice functions! Thanks
Torque Owner Jason Cahill
Default Studio Name
Description: Converts an rgba value into a corresponding hlsa value.
Parameter: %rgba - a string containing red, green, blue, and alpha components (eg, "1 1 1 1" for pure white). r, g, b, and a are in the range [0, 1].
Result: %hlsa - a string containing hue, lightness, saturation, and alpha components (eg "0 1 0 1" for white). h in [0, 360], while l, s, and a are in the range [0, 1].
Color::HLSA2RGBA
Description: Converts an hlsa value into the corresponding rgba value.
Parameter: %hlsa - a string containing hue, lightness, saturation, and alpha components.
Result: %rgba - a string containing the red, green, blue, and alpha components.
This implementation is based on (and bug fixed) from Computer Graphics: Principles and Practice, Foley, van Dam, Feiner, Hughes, Second Edition, pages 595 - 596.