Attract-Mode Support > Scripting
GLSL colorizer and color conversion routines
(1/1)
zpaolo11x:
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: ---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);
}
--- End code ---
This is a sample layout
--- Code: ---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
--- End code ---
zpaolo11x:
And this is a simple "desaturate" filter, it uses luminosity from HSL instead of HSV, it looks more natural in my opinion...
--- Code: ---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);
}
--- End code ---
Navigation
[0] Message Index
Go to full version