Ios 如何为rgb到hsl转换创建lut
我需要使用着色器进行rgb到hsl的转换,反之亦然。。我试着用编程的方式做所有的事情,但是太慢了。。。所以我阅读了关于转换查找表LUT的内容,但我不知道如何创建它以及它必须包含什么。。。我还需要知道如何将lut大小减少到所需的最小值,因为否则它可能对于iphone内存来说太大了。要处理的帧,因此要处理的纹理为32位rgba-->因此rgb为每像素24位-->8位 我真的很感激任何帮助,但我专注于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的创建,并且只有在很好地解释了如何使用它之后。。。因为我的问题是如何创造它 以下是着色器代码:
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显然太大了,所以你需要对它进行量化,但随后你会失去精度。你可能会发现优化转换会得到更好的结果。我编辑了问题并附上了代码…我希望现在更容易理解艾普利。。。