#version 140 #line 0 7893004 vec4 alpha_blend(vec4 over, vec4 under) { // Alpha blend two colors returning the resulting color pre-multiplied by its alpha // and its alpha. // See https://en.wikipedia.org/wiki/Alpha_compositing float alpha = mix(under.a, 1.0f, over.a); vec3 combined_color = mix(under.rgb * under.a, over.rgb, over.a); return vec4(combined_color, alpha); } vec4 alpha_blend_premul(vec4 over, vec4 under) { // Same as alpha_blend() except that it assumes over and under are both premultiplied. float inv_over_alpha = 1.0f - over.a; float alpha = over.a + under.a * inv_over_alpha; return vec4(over.rgb + under.rgb * inv_over_alpha, alpha); } vec4 alpha_blend_premul(vec4 over, vec3 under) { // same as alpha_blend_premul with under_alpha = 1 outputs a blended color // with alpha 1 which is effectively pre-multiplied since alpha is 1 float inv_over_alpha = 1.0f - over.a; return vec4(over.rgb + under.rgb * inv_over_alpha, 1.0); } #line 0 7893003 #line 0 7893005 // Return 0 if x < 1 otherwise 1 #define zero_or_one(x) step(1.f, x) // condition must be zero or one. When 1 thenval is returned otherwise elseval #define if_one_then(condition, thenval, elseval) mix(elseval, thenval, condition) // a < b ? thenval : elseval #define if_less_than(a, b, thenval, elseval) mix(thenval, elseval, step(b, a)) vec4 vec4_premul(vec3 rgb, float a) { return vec4(rgb * a, a); } vec4 vec4_premul(vec4 rgba) { return vec4(rgba.rgb * rgba.a, rgba.a); } #line 1 7893003 #define IMAGE uniform sampler2D image; #ifdef ALPHA_MASK uniform vec3 amask_fg; uniform vec4 amask_bg_premult; #else uniform float extra_alpha; #endif in vec2 texcoord; out vec4 output_color; void main() { vec4 color = texture(image, texcoord); #ifdef ALPHA_MASK color = vec4(amask_fg, color.r); color = vec4_premul(color); color = alpha_blend_premul(color, amask_bg_premult); #else color.a *= extra_alpha; #if 0 color = vec4_premul(color); #endif #endif output_color = color; }