如何为rgb创建lut到hsl转换

时间:2012-07-12 12:01:43

标签: ios opengl-es shader rgb hsl

我需要使用着色器做一个rgb到hsl,反之亦然转换..我试图以编程方式做所有但是它太慢了......所以我读了关于转换的查找表,LUT,但我不知道如何创建它以及它必须包含什么...我还需要知道如何将lut大小减小到所需的最小值,否则它可能对于iphone内存来说太大了。要处理的帧,所以要处理的纹理是32位rgba - >所以rgb是24位 - >每像素8位。

我真的很感激任何帮助,但只关注了lut的创造,并且只是在对如何使用它的一个很好的解释之后...因为我的问题是如何创建它。

以下是着色器代码:

顶点着色器

attribute vec4 position;
attribute mediump vec4 textureCoordinate;
varying mediump vec2 coordinate;

void main()
{
    gl_Position = position;
    coordinate = textureCoordinate.xy;
}

片段着色器

varying highp vec2 coordinate;
uniform sampler2D videoframe;

/*
 Hue, Saturation, Luminance
*/
highp vec3 RGBToHSL(highp vec3 color){
    highp vec3 hsl;;

    highp float fmin = min(min(color.r, color.g), color.b);
    highp float fmax = max(max(color.r, color.g), color.b);    

    highp float delta = fmax - fmin;

    hsl.z = (fmax + fmin)/2.0; 

    if(delta == 0.0) { //gray no chroma
        hsl.x = 0.0;
        hsl.y = 0.0;
    }
    else{
        if(hsl.z < 0.5){ //Saturation
            hsl.y = delta/(fmax + fmin);
        }
        else{
            hsl.y = delta/ (2.0 - fmax - fmin);
        }

//        //NO BRANCHING
//        highp float br1 = float(hsl.z<0.5);    
//        highp float br2 = float(hsl.z>=0.5);
//        highp float denominator = (2.0*(sign(br2))) + (sign(br1)*(fmax+fmin)) - (sign(br2)*(fmax+fmin));
//    
//        hsl.y = delta/denominator;        
//        //

        highp float deltaR = (((fmax - color.r)/6.0) + (delta / 2.0)) / delta;
        highp float deltaG = (((fmax - color.g)/6.0) + (delta / 2.0)) / delta;
        highp float deltaB = (((fmax - color.b)/6.0) + (delta / 2.0)) / delta; 

        if(color.r == fmax){ //Hue
            hsl.x = deltaB - deltaG; 
        }
        else if(color.g == fmax){
            hsl.x = (1.0/3.0) + deltaR - deltaB; 
        }
        else if(color.b == fmax){
            hsl.x = (2.0/3.0) + deltaG - deltaR;
        }

        if(hsl.x < 0.0){
            hsl.x = hsl.x + 1.0;
        }
        else if(hsl.x > 1.0){
            hsl.x = hsl.x - 1.0;
        }
    }

 //    //NO BRANCHING
 //    highp float br3 =  sign(float(delta!=0.0));
 //    
 //    hsl.x = hsl.x * br3;
 //    hsl.y = hsl.y * br3;    
 //    //

    return hsl;
}

highp float HueToRGB(highp float f1, highp float f2, highp float hue){

//    //NO BRANCHING
//    highp float br1 = sign(float(hue<0.0));
//    highp float br2 = sign(float(hue>1.0));    
//    hue = hue + (br1 * 1.0) - (br2 * 1.0);
//    //

    highp float res;
    if((6.0 * hue) < 1.0){
        res = f1 + (f2 - f1) * 6.0 * hue;
    }
    else if((2.0*hue)<1.0){
        res = f2;
    }
    else if((3.0*hue)<2.0){
        res = f1 + (f2-f1) * ((2.0/3.0) - hue) * 6.0;
    }
    else{
        res = f1;
    }

 //    //NO BRANCHING
 //    highp float br3 = sign(float((6.0 * hue) < 1.0));
 //    highp float br4 = sign(float((2.0*hue)<1.0));
 //    highp float br5 = sign(float((3.0*hue)<2.0));    
//
//    res = f1;
//    res = br3 * (f1 + (f2 - f1) * 6.0 * hue);
//    res = br4 * f2;
//    res = br5 * (f1 + (f2-f1) * ((2.0/3.0) - hue) * 6.0);    
 //    //


    return res;
}

highp vec3 HSLToRGB(highp vec3 hsl){
    highp vec3 rgb;

    if(hsl.y == 0.0){
        rgb = vec3(hsl.z);
    }
    else{
        highp float f2;

        if(hsl.z<0.5){
            f2 = hsl.z * (1.0 + hsl.y);
        }
        else{
            f2 = (hsl.z + hsl.y) - (hsl.y * hsl.z);
        }

//         //NO BRANCHING
//        highp float br2 = sign(float(hsl.z<0.5)); 
//        highp float br3 = sign(float(hsl.z>=0.5));         
//        f2 = br2 * (hsl.z * (1.0 + hsl.y)) + br3 * ((hsl.z + hsl.y) - (hsl.y * hsl.z));
//        //

        highp float f1 = 2.0 * hsl.z - f2;

        rgb.r = HueToRGB(f1,f2, hsl.x + (1.0/3.0));
        rgb.g = HueToRGB(f1,f2, hsl.x);
        rgb.b = HueToRGB(f1,f2, hsl.x - (1.0/3.0));        
    }

//        highp float br1 = sign(float(hsl.y == 0.0));
//        highp float not_br1 = sign(float(hsl.y != 0.0));
//        rgb = (rgb) * (not_br1,not_br1,not_br1) + (br1,br1,br1) *  vec3(hsl.z,hsl.z,hsl.z);    

    return rgb;
}

void main()  
{
    //GrayScale
    /*
    highp float grey = dot(texture2D(videoframe, coordinate).rgb, vec3(0.299, 0.587, 0.114));
gl_FragColor = vec4(grey, grey, grey, 1.0);
    */


    //Sepia
    /*
    highp float grey = dot(texture2D(videoframe, coordinate).rgb, vec3(0.299, 0.587, 0.114));
gl_FragColor = vec4(grey * vec3(1.2, 1.0, 0.8), 1.0);
    */

    //Other Effect
    ////**MULTIPLY STEP (Blending Multiply Mode)
    highp vec4 paleYellow = vec4(250.0/255.0, 220.0/255.0, 175.0/255.0, 1.0);
    highp vec3 paleYellowLuminance = RGBToHSL(paleYellow.xyz);

    highp vec4 FragColor = texture2D(videoframe, coordinate);
    highp vec3 fragLuminance = RGBToHSL(FragColor.xyz);

    highp float newLuminance = paleYellowLuminance.z * fragLuminance.z;
    highp vec3 fragHSL = vec3(fragLuminance.xy, newLuminance);

    ////
    gl_FragColor = vec4(HSLToRGB(fragHSL), 1.0); //this is very slow (if i comment this, and uncomment the last line to avoid crash, about 20 f/s otherwise 5-6 so the problem, obviously is here. I tried debranching too, as you can see looking at commented code, but no results...)
    //

    //gl_FragColor = texture2D(videoframe, coordinate);

}

解决!!!

0 个答案:

没有答案