I need to do a rgb to hsl and vice versa conversion using shaders.. I tried to do all programmatically but it is too slow... So i read about lookup table for conversion, LUT, but i don't know how to create it and what it has to contain... I need also to know how to reduce the lut size to the minimum required because otherwise it will probably be too big for iphone memory. The frame to process, so the texture to process is 32 bit rgba --> so the rgb is 24 bit --> 8bit per pixel.
I really appreciate any help but focused to the creation of the lut and only after a good explaination of that about how to use it... Because my problem is how to create it.
Here is the shaders code:
Vertex Shader
attribute vec4 position;
attribute mediump vec4 textureCoordinate;
varying mediump vec2 coordinate;
void main()
{
gl_Position = position;
coordinate = textureCoordinate.xy;
}
Fragment Shader
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);
}
SOLVED!!!