uniform sampler2D tex; uniform float red; uniform float green; uniform float blue; uniform float in_slope; uniform float out_slope; uniform float tolerance; uniform float tolerance_in; uniform float tolerance_out; uniform float sat; uniform float min_s; uniform float min_s_in; uniform float min_s_out; uniform float min_v; uniform float min_v_in; uniform float min_v_out; uniform float max_v; uniform float max_v_in; uniform float max_v_out; uniform float spill_threshold; uniform float spill_amount; uniform float alpha_offset; uniform float hue_key; uniform float saturation_key; uniform float value_key; void main() { vec4 color = texture2D(tex, gl_TexCoord[0].st); /* Contribution to alpha from each component */ float alpha_value = 1.0; float alpha_value_max = 1.0; float alpha_hue = 1.0; float alpha_saturation = 1.0; bool has_match = true; vec4 color2; /* Convert to HSV */ color2 = yuv_to_rgb(color); color2 = rgb_to_hsv(color2); /* Hue wrap */ if(color2.r <= hue_key - tolerance_in * 180.0) color2.r += 360.0; else if(color2.r >= hue_key + tolerance_in * 180.0) color2.r -= 360.0; /* Hue is completely out of range */ if (tolerance == 0.0) alpha_hue = 1.0; else if (abs(color2.r - hue_key) < tolerance_in * 180.0) alpha_hue = 0.0; else if ((out_slope != 0.0 ) && (abs(color2.r - hue_key) < tolerance * 180.0)) /* If using slope, scale alpha between 0 and 1 / 2 */ alpha_hue = abs(color2.r - hue_key) / tolerance / 360.0; else if (abs(color2.r - hue_key) < tolerance_out * 180.0) /* If no slope, scale alpha between 1/2 and 1 */ alpha_hue = abs(color2.r - hue_key) / tolerance_out / 360.0; else has_match = false; /* Test saturation */ if (has_match) { if (min_s == 0.0) alpha_saturation = 0.0; else if ( color2.g - sat >= min_s_in ) alpha_saturation = 0.0; else if ((out_slope != 0.0) && ( color2.g - sat > min_s ) ) alpha_saturation = (color2.g - sat - min_s) / (min_s * 2.0); else if ( color2.g - sat > min_s_out ) alpha_saturation = (color2.g - sat - min_s_out) / (min_s_out * 2.0); else has_match = false; } /* Test value over minimum */ if (has_match) { if (min_v == 0.0) alpha_value = 0.0; else if ( color2.b >= min_v_in ) alpha_value = 0.0; else if ((out_slope != 0.0) && ( color2.b > min_v ) ) alpha_value = (color2.b - min_v) / (min_v * 2.0); else if ( color2.b > min_v_out ) alpha_value = (color2.b - min_v_out) / (min_v_out * 2.0); else has_match = false; } /* Test value under maximum */ if (has_match) { if (max_v == 0.0) alpha_value_max = 1.0; else if (color2.b <= max_v_in) alpha_value_max = 0.0; else if ((out_slope != 0.0) && (color2.b < max_v)) alpha_value_max = (color2.b - max_v) / (max_v * 2.0); else if (color2.b < max_v_out) alpha_value_max = (color2.b - max_v_out) / (max_v_out * 2.0); else has_match = false; } /* Take largest component as the alpha */ if (has_match) color2.a = max (max (alpha_hue, alpha_value), max (alpha_saturation, alpha_value_max)); /* Spill light processing */ if ((abs(color2.r - hue_key) < spill_threshold * 180.0) || ((abs(color2.r - hue_key) > 360.0) && (abs(color2.r - hue_key) - 360.0 < spill_threshold * 180.0))) { /* Modify saturation based on hue contribution */ color2.g = color2.g * spill_amount * abs(color2.r - hue_key) / (spill_threshold * 180.0); /* convert back to native colormodel */ color2 = hsv_to_rgb(color2); color.rgb = rgb_to_yuv(color2).rgb; } /* Convert mask into image */ gl_FragColor = show_mask(color, color2); }