Color conversion scripts

From Second Life Wiki

Jump to: navigation, search

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

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


HSV to RGB

 
// 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;
}
 
Personal tools