Author Topic: GLSL colorizer and color conversion routines  (Read 4225 times)

zpaolo11x

  • Hero Member
  • *****
  • Posts: 1245
    • View Profile
    • My deviantart page
GLSL colorizer and color conversion routines
« on: October 09, 2018, 07:46:44 AM »
I jsut developed a small shader for colorizing, it uses HSL color space which looks much better than HSV. But in the code you can find some useful color conversion functions that you can use for many purposes like desaturation, hue rotation etc.

The shader requires an HSL vector of three values that are used for colorizing, plus a texture mix value if you want to blend (in RGB) the colorized with the default image.

Code: [Select]
uniform sampler2D texture;
uniform vec3 hsl;
uniform float texmix;

vec3 hsl2rgb( in vec3 c )
{
    vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 );
    return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));
}

vec3 rgb2hsl( in vec3 c ){
  float h = 0.0;
float s = 0.0;
float l = 0.0;
float r = c.r;
float g = c.g;
float b = c.b;
float cMin = min( r, min( g, b ) );
float cMax = max( r, max( g, b ) );

l = ( cMax + cMin ) / 2.0;
if ( cMax > cMin ) {
float cDelta = cMax - cMin;
       
        //s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); Original
s = l < .0 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) );
       
if ( r == cMax ) {
h = ( g - b ) / cDelta;
} else if ( g == cMax ) {
h = 2.0 + ( b - r ) / cDelta;
} else {
h = 4.0 + ( r - g ) / cDelta;
}

if ( h < 0.0) {
h += 6.0;
}
h = h / 6.0;
}
return vec3( h, s, l );
}


vec3 rgb2hsv(vec3 c)
{
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv2rgb(vec3 c)
{
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

void main()
{   

vec2 uv = gl_TexCoord[0].xy;

vec4 t0 = texture2D(texture, uv);
vec3 hsl0 = rgb2hsl (t0.rgb);

vec3 hsl1 = vec3(hsl.x,hsl.y,hsl0.z);

vec3 tch = hsl2rgb (hsl1);


gl_FragColor = vec4(mix(hsl.z*tch.xyz,t0.xyz,texmix) , gl_Color.a*t0.a);

}

This is a sample layout

Code: [Select]
local pic1 = fe.add_artwork("snap",0,0,400,400)
pic1.video_flags = Vid.ImagesOnly
pic1.preserve_aspect_ratio = false

local pic2 = fe.add_artwork("snap",400,0,400,400)
pic2.video_flags = Vid.ImagesOnly
pic2.preserve_aspect_ratio = false

local pic3 = fe.add_artwork("snap",800,0,400,400)
pic3.video_flags = Vid.ImagesOnly
pic3.preserve_aspect_ratio = false

local colorshader1 = fe.add_shader(Shader.Fragment,"colorizer.glsl")
colorshader1.set_texture_param("texture")
colorshader1.set_param("hsl",0.6,0.5,1.0)
colorshader1.set_param("texmix",0.0)
pic1.shader = colorshader1

local colorshader2 = fe.add_shader(Shader.Fragment,"colorizer.glsl")
colorshader2.set_texture_param("texture")
colorshader2.set_param("hsl",0.6,1.0,1.0)
colorshader2.set_param("texmix",0.0)
pic2.shader = colorshader2


« Last Edit: October 09, 2018, 09:30:20 AM by zpaolo11x »

zpaolo11x

  • Hero Member
  • *****
  • Posts: 1245
    • View Profile
    • My deviantart page
Re: GLSL colorizer and color conversion routines
« Reply #1 on: October 09, 2018, 10:18:07 AM »
And this is a simple "desaturate" filter, it uses luminosity from HSL instead of HSV, it looks more natural in my opinion...

Code: [Select]
uniform sampler2D texture;

float luminosity( in vec3 c ){
float s = 0.0;
float l = 0.0;

float cMin = min( c.r, min( c.g, c.b ) );
float cMax = max( c.r, max( c.g, c.b ) );
l = ( cMax + cMin ) / 2.0;

if ( cMax > cMin ) {
float cDelta = cMax - cMin;
       
        //s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) );
s = l < .0 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) );
       
}
return float( l );
}


void main()
{   

vec2 uv = gl_TexCoord[0].xy;
vec4 t0 = texture2D(texture, uv);
float hsl0 = luminosity (t0.rgb);

gl_FragColor = vec4(vec3(hsl0) , gl_Color.a*t0.a);

}