龙芯爱好者的日常!
返回

RGB与HSL互转的GLSL代码

2020-03-03 152 0

uniform sampler2D qt_Texture0;

varying vec4 qt_TexCoord0;

 

uniform float contrast;     //对比度:-1 ~ 10表示无变化,负数降低对比度,正数增大对比度。

uniform float bright;       //亮度:-1 ~ 10表示无变化,负数降低亮度,正数增大亮度。

uniform float saturation;   //饱和度:-1 ~ 10表示无变化,负数降低饱和度,正数增大饱和度。

uniform float hue;          //色相:-1 ~ 10表示无变化,负数逆时针旋转(360度),正数顺时针旋转(360度)。

                            //色相可把参数范围控制为 -0.5 ~ 0.5,表示正负180度,合为360度。

                            //其它参数(对比度、亮度、饱和度)也可以缩小值范围,避免用户调整得过大。

vec3 rgb2hsl(vec3 rgb)

{

    //返回的 vec3 中, r 表示 hg 表示 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;

}



顶部