uniform sampler2D qt_Texture0;
varying vec4 qt_TexCoord0;
uniform float contrast; //对比度:-1 ~ 1。 0表示无变化,负数降低对比度,正数增大对比度。
uniform float bright; //亮度:-1 ~ 1。 0表示无变化,负数降低亮度,正数增大亮度。
uniform float saturation; //饱和度:-1 ~ 1。 0表示无变化,负数降低饱和度,正数增大饱和度。
uniform float hue; //色相:-1 ~ 1。 0表示无变化,负数逆时针旋转(360度),正数顺时针旋转(360度)。
//色相可把参数范围控制为 -0.5 ~ 0.5,表示正负180度,合为360度。
//其它参数(对比度、亮度、饱和度)也可以缩小值范围,避免用户调整得过大。
vec3 rgb2hsl(vec3 rgb)
{
//返回的 vec3 中, r 表示 h, g 表示 s, b 表示 l,均为归一化的值,包括色相 s。
float h, s, l, v;
float maxValue = max(rgb.r, max(rgb.g, rgb.b));
float minValue = min(rgb.r, min(rgb.g, rgb.b));
v = maxValue - minValue;
l = (maxValue + minValue) * 0.5;
if (v == 0.0 || l == 0.0)
{
s = h = 0.0;
}
else
{
//计算色深
//s = v / ( 1.0 - abs( 2.0 * l - 1.0));
s = l <= 0.5 ? v/(2.0*l) : v/(2.0-2.0*l);
if (maxValue == rgb.r)
h = ((rgb.g - rgb.b) / v + (rgb.g < rgb.b ? 6.0 : 0.0)) / 6.0;
else if (maxValue == rgb.g)
h = ((rgb.b - rgb.r) / v + 2.0) / 6.0;
else
h = ((rgb.r - rgb.g) / v + 4.0) / 6.0;
}
return vec3(h,s,l);
}
float hue2rgb(float p, float q, float t)
{
if (t < 0.0)
++t;
else if (t > 1.0)
--t;
if (t < 1.0/6.0) return p + (q - p) * 6.0 * t;
if (t < 1.0/2.0) return q;
if (t < 2.0/3.0) return p + (q - p) * (2.0 / 3.0 - t) * 6.0;
return p;
}
vec3 hsl2rgb(float h, float s, float l)
{
float r, g, b;
if (s == 0.0)
{
r = g = b = l;
}
else
{
float q = l < 0.5 ? l * (1.0 + s) : l + s - l * s;
float p = 2.0 * l - q;
r = hue2rgb(p, q, h + 1.0/3.0);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1.0/3.0);
}
return vec3(r, g, b);
}
void main(void)
{
vec4 pix = texture2D(qt_Texture0, qt_TexCoord0.st);
float c = contrast >= 0.0 ? 1.0 + contrast * 9.0 : 1.0 + contrast * 9.0 / 10.0;
float b = bright >= 0.0 ? 1.0 + bright * 9.0 : 1.0 + bright * 9.0 / 10.0;
float s = saturation >= 0.0 ? 1.0/(1.0 + saturation * 9.0) : 1.0 + saturation * 1.0;
vec3 hsl = rgb2hsl(pix.rgb);
if (contrast >= 0.0)
{
hsl.b = hsl.b <= 0.5 ? pow(hsl.b * 2.0, c) * 0.5 : (1.0 - pow((1.0 - (hsl.b - 0.5) * 2.0), c)) * 0.5 + 0.5;
}
else
{
hsl.b = hsl.b * c + (1.0 - c) * 0.5;
hsl.g = hsl.g * c;
}
hsl.b = bright >= 0.0 ? 1.0 - pow( 1.0 - hsl.b, b) : pow( hsl.b, 1.0 / b);
hsl.g = saturation >= 0.0 ? pow( hsl.g, s) : hsl.g * s;
hsl.r = hsl.r + hue + 2.0;
hsl.r -= floor(hsl.r);
pix.rgb = hsl2rgb(hsl.r, hsl.g, hsl.b);
gl_FragColor = pix;
}
转载请注明:《RGB与HSL互转的GLSL代码》