Color conversion scripts
| LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
The following functions convert between LSL color in Red Green Blue (RGB) format and color in Hue Saturation Value (HSV) format. The functions are based on "c" algorithms from c color conversion but required some debugging and extensive re-working to fit them in to LSL. For a discussion of HSV color format please see the wikipedia entry at HSV Color
RGB to HSV
<lsl> // by Sally LaSalle, code released to the public domain under GNU GPL version 3.0 license. // you are free to use, and you are free to donate to me if you wish!! :P
// takes an RGB color as a vector, with range <float R[0,1], float G[0,1], float B[0,1]> // returns a vector with HSV ranged from <float H[0,360], float S[0,1], float V[0,1]> // H ranges smoothly from Red=0, Yellow=60, Green=120, Cyan=180, Blue=240, Violet=300 and back to Red
vector RGBtoHSV( vector rgb ) {
float R = rgb.x;
if (R<0) // catch malformed input
R=0;
else if (R>1)
R=1;
float G = rgb.y;
if (G<0) // catch malformed input
G=0;
else if (G>1)
G=1;
float B = rgb.z;
if (B<0) // catch malformed input
B=0;
else if (B>1)
B=1;
float H;
float S;
float V;
list rgbList = [R, G, B]; // list used to get min and max
float min;
float max;
float achromatic; // =1 if R=G=B
float delta;
vector hsv; // the return HSV vector
min = llListStatistics(LIST_STAT_MIN, rgbList); //MIN of ( R, G, B );
max = llListStatistics(LIST_STAT_MAX, rgbList); //MAX of ( R, G, B );
if (R==G && G==B)
achromatic = 1; // it is a shade of grey, white or black
else
achromatic = 0;
V = max; // V = brightness Value form 0 to 1 delta = max - min;
if( max != 0 )
S = delta / max; // S = saturation from 0 to 1
else {
// R = G = B = 0 // S = 0, V = 0, H = 0
S = 0;
V = 0;
H = 0;
hsv.x = H;
hsv.y = S;
hsv.z = V;
return hsv; //H = S = V = 0
}
if (achromatic == 1)
H = 0;
else if( R == max )
H = 0 + ( G - B ) / delta; // between red & yellow
else if( G == max )
H = 2 + ( B - R ) / delta; // between yellow & cyan
else
H = 4 + ( R - G ) / delta; // between cyan & red
H *= 60; // H is traditionally a figure between 0 and 360 degrees
if( H < 0 )
H += 360;
hsv.x = H; hsv.y = S; hsv.z = V; return hsv;
} </lsl>
HSV to RGB
<lsl> // by Sally LaSalle, code released to the public domain under GNU GPL version 3.0 license. // you are free to use, and you are free to donate to me if you wish!! :P
// takes a vector encoded Hue Saturation Value (HSV) triplet // HSV should be entered with floats the ranges: <float H(0 to 360), float S(0 to 1),float V(0 to 1)> // And Returns a vector encode Red Green Blue (RGB) color triplet // RGB will be returned with floats in ranges <float R(0 to 1),float G(0 to 1),float B(0 to 1)>
vector HSVtoRGB( vector hsv ) {
integer i;
float H = hsv.x;
if (H<0) // catch malformed H input
H=0;
else if (H>360)
H=360;
float S = hsv.y;
if (S<0) // catch malformed S input
S=0;
else if (S>1)
S=1;
float V = hsv.z;
if (V<0) // catch malformed V input
V=0;
else if (V>1)
V=1;
float R;
float G;
float B;
float f; // variables for calculating base color mixing around the "spectrum circle"
float p;
float q;
float t;
vector rgb;
if( S == 0 ) { // achromatic (grey) simply set R,G, & B = Value
R = V;
G = V;
B = V;
rgb.x = R;
rgb.y = G;
rgb.z = B;
return rgb;
}
H /= 60; // Hue factored into range 0 to 5 i = llFloor( H ); // integer floor of Hue f = H - i; // factorial part of H
p = V * ( 1 - S ); q = V * ( 1 - S * f ); t = V * ( 1 - S * ( 1 - f ) );
if (i==0){
R = V;
G = t;
B = p;
} else if (i==1){
R = q;
G = V;
B = p;
} else if (i==2){
R = p;
G = V;
B = t;
} else if (i==3){
R = p;
G = q;
B = V;
} else if (i==4){
R = t;
G = p;
B = V;
} else {
R = V;
G = p;
B = q;
}
rgb.x = R;
rgb.y = G;
rgb.z = B;
return rgb;
} </lsl>
HSL to RGB
<lsl> //HSL to RGB conversion function. By Cobalt Arkright. Released to the public under GNU GPL version 3.0 license. //Takes a vector encoded HSL triplet and outputs a vector encoded RGB triplet. //Input values should be in the following ranges: <float H(0 to 1), float S(0 to 1), float L(0 to 1). //If you wish to use H(0 to 360), comment out the lines 6, 7, and 8, then remove the comment for lines 11, 12, and 13. vector HSLtoRGB (vector hsl) { //Catch malformed H input for H(0 to 1) if (hsl.x < 0)hsl.x = 0; else if (hsl.x > 1.0)hsl.x = 1.0;
//Catch malformed H input for H(0 to 360) //if (hsl.x < 0) hsl.x = 0; //else if (hsl.x > 360) hsl.x = 360; //hsl.x = hsl.x/360;
//Catch malformed S input if (hsl.y < 0)hsl.y = 0; else if (hsl.y > 1.0)hsl.y = 1.0;
//Catch malformed L input if (hsl.z < 0)hsl.z = 0; else if (hsl.z > 1.0)hsl.z = 1.0;
//Special case: When S = 0, the result is monochromatic, and R = B = G = L. if (hsl.y == 0){ rgb.x = rgb.y = rgb.z = hsl.z; return rgb; }
//Declare required variables vector rgb; float q; float p; float tr; float tg; float tb;
//Set up temporary values for conversion if (hsl.z < 0.5)q = hsl.z*(1.0+hsl.y); else if (0.5 <= hsl.z) q = hsl.z+hsl.y-(hsl.z*hsl.y); p = 2*hsl.z-q; tr = hsl.x+0.3333; tg = hsl.x; tb = hsl.x-0.3333;
//Normalize temporary R value if (tr < 0 )tr = tr + 1.0; else if (tr > 1.0)tr = tr - 1.0;
//Normalize temporary G value if (tg < 0 )tg = tg + 1.0; else if (tg > 1.0)tg = tg - 1.0;
//Normalize temporary B value if (tb < 0 )tb = tb + 1.0; else if (tb > 1.0)tb = tb - 1.0;
//Calculate R value if (tr < 0.1666)rgb.x = p+((q-p)*6*tr); else if (0.1666 <= tr < 0.5)rgb.x = q; else if (0.5 <= tr < 0.6666)rgb.x = p+((q-p)*6*(0.6666-tr)); else if (0.6666 <= tr) rgb.x = p;
//Calculate G value if (tg < 0.1666)rgb.y = p+((q-p)*6*tg); else if (0.1666 <= tg < 0.5)rgb.y = q; else if (0.5 <= tg < 0.6666)rgb.y = p+((q-p)*6*(0.6666-tg)); else if (0.6666 <= tg) rgb.y = p;
//Caluclate B value if (tb < 0.1666)rgb.z = p+((q-p)*6*tb); else if (0.1666 <= tb < 0.5)rgb.z = q; else if (0.5 <= tb < 0.6666)rgb.z = p+((q-p)*6*(0.6666-tb)); else if (0.6666 <= tb) rgb.z = p;
//Return the result return rgb; } </lsl>