Ios 如何为rgb到hsl转换创建lut

Ios 如何为rgb到hsl转换创建lut,ios,opengl-es,shader,rgb,hsl,Ios,Opengl Es,Shader,Rgb,Hsl,我需要使用着色器进行rgb到hsl的转换,反之亦然。。我试着用编程的方式做所有的事情,但是太慢了。。。所以我阅读了关于转换查找表LUT的内容,但我不知道如何创建它以及它必须包含什么。。。我还需要知道如何将lut大小减少到所需的最小值,因为否则它可能对于iphone内存来说太大了。要处理的帧,因此要处理的纹理为32位rgba-->因此rgb为每像素24位-->8位 我真的很感激任何帮助,但我专注于lut的创建,并且只有在很好地解释了如何使用它之后。。。因为我的问题是如何创造它 以下是着色器代码:

我需要使用着色器进行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);

}
改变highp vec2坐标;
二维视频帧的均匀采样;
/*
色调、饱和度、亮度
*/
highp vec3 RGBToHSL(highp vec3颜色){
高vec3 hsl;;
highp float fmin=min(min(color.r,color.g),color.b);
highp float fmax=最大值(最大值(颜色r,颜色g),颜色b);
高位浮动增量=fmax-fmin;
hsl.z=(fmax+fmin)/2.0;
如果(delta==0.0){//灰色无色度
hsl.x=0.0;
hsl.y=0.0;
}
否则{
如果(hsl.z<0.5){//饱和
hsl.y=δ/(fmax+fmin);
}
否则{
hsl.y=δ/(2.0-fmax-fmin);
}
////没有分支
//highp float br1=浮动(hsl.z=0.5);
//高位浮点分母=(2.0*(符号(br2))+(符号(br1)*(fmax+fmin))-(符号(br2)*(fmax+fmin));
//    
//hsl.y=增量/分母;
//        //
高浮点deltaR=((fmax-color.r)/6.0)+(delta/2.0))/delta;
HighpFloatDeltag=((fmax-color.g)/6.0)+(delta/2.0))/delta;
高浮点deltaB=((fmax-color.b)/6.0)+(delta/2.0))/delta;
如果(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;
}
如果(hsl.x<0.0){
hsl.x=hsl.x+1.0;
}
否则如果(hsl.x>1.0){
hsl.x=hsl.x-1.0;
}
}
////没有分支
//highp float br3=符号(浮动(增量=0.0));
//    
//hsl.x=hsl.x*br3;
//hsl.y=hsl.y*br3;
//    //
返回hsl;
}
highp float色调RGB(highp float f1、highp float f2、highp float色调){
////没有分支
//highp float br1=符号(浮点(hue1.0));
//色调=色调+(br1*1.0)-(br2*1.0);
//    //
高浮点分辨率;
如果((6.0*色调)<1.0){
res=f1+(f2-f1)*6.0*色调;
}

否则如果((2.0*色调)你读过吗?你能发布显示你如何进行转换的代码吗?创建一个24位LUT显然太大了,所以你需要对它进行量化,但随后你会失去精度。你可能会发现优化转换会得到更好的结果。我编辑了问题并附上了代码…我希望现在更容易理解艾普利。。。