0 true #version 150 //OVE shader_name: Hue filter //OVE shader_description: Transform an image into a gray scale, except for one color tone. //OVE shader_description: Credits to Iñigo Quiles and https://thebookofshaders.com/06/ //OVE shader_version: 0.1 //OVE main_input_name: Input uniform sampler2D tex_in; //OVE name: color //OVE type: COLOR //OVE default: RGBA(0.2, 0.8, 0.2, 1) //OVE description: key color to preserve. Works better with high saturation uniform vec4 reference; //OVE name: hue span //OVE type: FLOAT //OVE flag: NOT_CONNECTABLE //OVE min: 0.0 //OVE max: 1.0 //OVE default: 0.2 //OVE description: tolerance in hue uniform float hue_span; //OVE name: satur. span //OVE type: FLOAT //OVE flag: NOT_CONNECTABLE //OVE min: 0.0 //OVE max: 1.0 //OVE default: 0.8 //OVE description: tolerance in saturation uniform float saturation_span; //OVE name: value span //OVE type: FLOAT //OVE flag: NOT_CONNECTABLE //OVE min: 0.0 //OVE max: 1.0 //OVE default: 0.8 //OVE description: tolerance in value uniform float value_span; //OVE name: show original //OVE type: BOOLEAN //OVE flag: NOT_CONNECTABLE, NOT_KEYFRAMABLE //OVE default: false //OVE description: see original image. Useful to pick a color uniform bool bypass; //OVE end // pixel coordinates in range [0..1]x[0..1] in vec2 ove_texcoord; // output color out vec4 frag_color; // ref: https://thebookofshaders.com/06/ vec3 rgb2hsb( in 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); } // Function from Iñigo Quiles // https://www.shadertoy.com/view/MsS3Wc vec3 hsb2rgb( 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 ); rgb = rgb*rgb*(3.0-2.0*rgb); return c.z * mix(vec3(1.0), rgb, c.y); } void main(void) { // [0]: hue; [1]: saturation; [2]: value; vec3 reference_hsb = rgb2hsb(reference.rgb); vec4 image_in = texture( tex_in, ove_texcoord); if (bypass) { frag_color = image_in; } else { vec3 hsb_texture = rgb2hsb( image_in.rgb); float hue_start = max( 0., reference_hsb[0] - hue_span); float hue_end = min( 1., reference_hsb[0] + hue_span); float saturation_start = max( 0., reference_hsb[1] - saturation_span); float saturation_end = min( 1., reference_hsb[1] + saturation_span); float value_start = max( 0., reference_hsb[2] - value_span); float value_end = min( 1., reference_hsb[2] + value_span); // change saturation according to limits. Set to zero if out of range; // use original if in range hsb_texture[1] = min( hsb_texture[1], step( hue_start, hsb_texture[0]) - step( hue_end, hsb_texture[0])); hsb_texture[1] = min( hsb_texture[1], step( saturation_start, hsb_texture[1]) - step( saturation_end, hsb_texture[1])); hsb_texture[1] = min( hsb_texture[1], step( value_start, hsb_texture[1]) - step( value_end, hsb_texture[2])); vec3 color = hsb2rgb(hsb_texture); frag_color = vec4(color,1.0); } } None 0 0 0.0884566456079483 0.49241504073143005 1 Rec.709 OETF sRGB sRGB OETF 0 0.2 0 1 0 1 false 1897878216656 -1 -1 -1 -1 {114bacfc-96b2-4738-8074-4390bbdc9b71} {9b0707c3-5c71-4cab-aa76-ee5e663a000f} 0 -1.77976 0.0350877