hsv_lerp.glsl (2613B)
1 /* See LICENSE for copyright details */ 2 #version 330 3 4 in vec2 fragTexCoord; 5 in vec4 fragColor; 6 7 out vec4 out_colour; 8 9 #define CM_RGB 0 10 #define CM_HSV 1 11 12 uniform int u_colour_mode; 13 uniform float u_radius; 14 uniform float u_border_thick; 15 uniform vec4 u_colours[3]; 16 uniform vec4 u_regions[4]; 17 uniform vec2 u_size; 18 19 /* input: h [0,360] | s,v [0, 1] * 20 * output: rgb [0,1] */ 21 vec3 hsv2rgb(vec3 hsv) 22 { 23 vec3 k = mod(vec3(5, 3, 1) + hsv.x / 60, 6); 24 k = max(min(min(k, 4 - k), 1), 0); 25 return hsv.z - hsv.z * hsv.y * k; 26 } 27 28 bool in_rounded_region(vec2 pos, vec4 min_max, float radius) 29 { 30 vec2 min_xy = min_max.xy; 31 vec2 max_xy = min_max.zw; 32 vec2 ulp = vec2(min_xy.x + radius, max_xy.y - radius); 33 vec2 urp = vec2(max_xy.x - radius, max_xy.y - radius); 34 vec2 blp = vec2(min_xy.x + radius, min_xy.y + radius); 35 vec2 brp = vec2(max_xy.x - radius, min_xy.y + radius); 36 37 bool ulr = length(ulp - pos) < radius; 38 bool urr = length(urp - pos) < radius; 39 bool blr = length(blp - pos) < radius; 40 bool brr = length(brp - pos) < radius; 41 bool rect = (pos.x > min_xy.x) && (pos.x < max_xy.x) && 42 (pos.y < max_xy.y - radius) && (pos.y > min_xy.y + radius); 43 bool upr = (pos.x > ulp.x) && (pos.x < urp.x) && (pos.y < max_xy.y) && (pos.y > min_xy.y); 44 45 return rect || ulr || urr || blr || brr || upr; 46 } 47 48 void main() 49 { 50 vec2 pos = gl_FragCoord.xy; 51 52 vec4 colour = vec4(0); 53 switch (u_colour_mode) { 54 case CM_RGB: 55 out_colour = vec4(0); 56 break; 57 case CM_HSV: 58 vec4 shift = vec4(vec2(u_border_thick), -vec2(u_border_thick)); 59 60 if (in_rounded_region(pos, u_regions[0], u_radius + u_border_thick)) { 61 colour.w = 1; 62 if (in_rounded_region(pos, u_regions[0] + shift, u_radius)) { 63 float scale = u_regions[0].w - u_regions[0].y; 64 colour = mix(vec4(1, u_colours[0].yzw), vec4(0, u_colours[0].yzw), 65 (pos.y - u_regions[0].y) / scale); 66 } 67 } else if (in_rounded_region(pos, u_regions[1], u_radius + u_border_thick)) { 68 colour.w = 1; 69 if (in_rounded_region(pos, u_regions[1] + shift, u_radius)) { 70 float scale = u_regions[1].w - u_regions[1].y; 71 colour = mix(u_colours[2], u_colours[1], 72 (pos.y - u_regions[1].y) / scale); 73 } 74 } else if (in_rounded_region(pos, u_regions[2], u_radius + u_border_thick)) { 75 colour.w = 1; 76 if (in_rounded_region(pos, u_regions[2] + shift, u_radius)) { 77 vec2 scale = u_regions[2].zw - u_regions[2].xy; 78 vec2 t = (pos - u_regions[2].xy) / scale; 79 colour = vec4(u_colours[0].x, t.x, t.y, 1); 80 } 81 } 82 colour.x *= 360; 83 out_colour = vec4(hsv2rgb(colour.xyz), colour.w); 84 break; 85 } 86 }