1// VERTEX_SHADER: 2// blend.glsl 3 4void main() { 5 gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0); 6 7 vUv = vec2(aUv.x, aUv.y); 8} 9 10// FRAGMENT_SHADER: 11// blend.glsl 12 13uniform int u_mode; 14uniform sampler2D u_source2; 15 16float 17combine (float source, float backdrop) 18{ 19 return source + backdrop * (1.0 - source); 20} 21 22vec4 23composite (vec4 Cs, vec4 Cb, vec3 B) 24{ 25 float ao = Cs.a + Cb.a * (1.0 - Cs.a); 26 vec3 Co = (Cs.a*(1.0 - Cb.a)*Cs.rgb + Cs.a*Cb.a*B + (1.0 - Cs.a)*Cb.a*Cb.rgb) / ao; 27 return vec4(Co, ao); 28} 29 30vec4 31normal (vec4 Cs, vec4 Cb) 32{ 33 return composite (Cs, Cb, Cs.rgb); 34} 35 36vec4 37multiply (vec4 Cs, vec4 Cb) 38{ 39 return composite (Cs, Cb, Cs.rgb * Cb.rgb); 40} 41 42vec4 43difference (vec4 Cs, vec4 Cb) 44{ 45 return composite (Cs, Cb, abs(Cs.rgb - Cb.rgb)); 46} 47 48vec4 49screen (vec4 Cs, vec4 Cb) 50{ 51 return composite (Cs, Cb, Cs.rgb + Cb.rgb - Cs.rgb * Cb.rgb); 52} 53 54float 55hard_light (float source, float backdrop) 56{ 57 if (source <= 0.5) 58 return 2.0 * backdrop * source; 59 else 60 return 2.0 * (backdrop + source - backdrop * source) - 1.0; 61} 62 63vec4 64hard_light (vec4 Cs, vec4 Cb) 65{ 66 vec3 B = vec3 (hard_light (Cs.r, Cb.r), 67 hard_light (Cs.g, Cb.g), 68 hard_light (Cs.b, Cb.b)); 69 return composite (Cs, Cb, B); 70} 71 72float 73soft_light (float source, float backdrop) 74{ 75 float db; 76 77 if (backdrop <= 0.25) 78 db = ((16.0 * backdrop - 12.0) * backdrop + 4.0) * backdrop; 79 else 80 db = sqrt (backdrop); 81 82 if (source <= 0.5) 83 return backdrop - (1.0 - 2.0 * source) * backdrop * (1.0 - backdrop); 84 else 85 return backdrop + (2.0 * source - 1.0) * (db - backdrop); 86} 87 88vec4 89soft_light (vec4 Cs, vec4 Cb) 90{ 91 vec3 B = vec3 (soft_light (Cs.r, Cb.r), 92 soft_light (Cs.g, Cb.g), 93 soft_light (Cs.b, Cb.b)); 94 return composite (Cs, Cb, B); 95} 96 97vec4 98overlay (vec4 Cs, vec4 Cb) 99{ 100 vec3 B = vec3 (hard_light (Cb.r, Cs.r), 101 hard_light (Cb.g, Cs.g), 102 hard_light (Cb.b, Cs.b)); 103 return composite (Cs, Cb, B); 104} 105 106vec4 107darken (vec4 Cs, vec4 Cb) 108{ 109 vec3 B = min (Cs.rgb, Cb.rgb); 110 return composite (Cs, Cb, B); 111} 112 113vec4 114lighten (vec4 Cs, vec4 Cb) 115{ 116 vec3 B = max (Cs.rgb, Cb.rgb); 117 return composite (Cs, Cb, B); 118} 119 120float 121color_dodge (float source, float backdrop) 122{ 123 return (source == 1.0) ? source : min (backdrop / (1.0 - source), 1.0); 124} 125 126vec4 127color_dodge (vec4 Cs, vec4 Cb) 128{ 129 vec3 B = vec3 (color_dodge (Cs.r, Cb.r), 130 color_dodge (Cs.g, Cb.g), 131 color_dodge (Cs.b, Cb.b)); 132 return composite (Cs, Cb, B); 133} 134 135 136float 137color_burn (float source, float backdrop) 138{ 139 return (source == 0.0) ? source : max ((1.0 - ((1.0 - backdrop) / source)), 0.0); 140} 141 142vec4 143color_burn (vec4 Cs, vec4 Cb) 144{ 145 vec3 B = vec3 (color_burn (Cs.r, Cb.r), 146 color_burn (Cs.g, Cb.g), 147 color_burn (Cs.b, Cb.b)); 148 return composite (Cs, Cb, B); 149} 150 151vec4 152exclusion (vec4 Cs, vec4 Cb) 153{ 154 vec3 B = Cb.rgb + Cs.rgb - 2.0 * Cb.rgb * Cs.rgb; 155 return composite (Cs, Cb, B); 156} 157 158float 159lum (vec3 c) 160{ 161 return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; 162} 163 164vec3 165clip_color (vec3 c) 166{ 167 float l = lum (c); 168 float n = min (c.r, min (c.g, c.b)); 169 float x = max (c.r, max (c.g, c.b)); 170 if (n < 0.0) c = l + (((c - l) * l) / (l - n)); 171 if (x > 1.0) c = l + (((c - l) * (1.0 - l)) / (x - l)); 172 return c; 173} 174 175vec3 176set_lum (vec3 c, float l) 177{ 178 float d = l - lum (c); 179 return clip_color (vec3 (c.r + d, c.g + d, c.b + d)); 180} 181 182float 183sat (vec3 c) 184{ 185 return max (c.r, max (c.g, c.b)) - min (c.r, min (c.g, c.b)); 186} 187 188vec3 189set_sat (vec3 c, float s) 190{ 191 float cmin = min (c.r, min (c.g, c.b)); 192 float cmax = max (c.r, max (c.g, c.b)); 193 vec3 res; 194 195 if (cmax == cmin) 196 res = vec3 (0, 0, 0); 197 else 198 { 199 if (c.r == cmax) 200 { 201 if (c.g == cmin) 202 { 203 res.b = ((c.b - cmin) * s) / (cmax - cmin); 204 res.g = 0.0; 205 } 206 else 207 { 208 res.g = ((c.g - cmin) * s) / (cmax - cmin); 209 res.b = 0.0; 210 } 211 res.r = s; 212 } 213 else if (c.g == cmax) 214 { 215 if (c.r == cmin) 216 { 217 res.b = ((c.b - cmin) * s) / (cmax - cmin); 218 res.r = 0.0; 219 } 220 else 221 { 222 res.r = ((c.r - cmin) * s) / (cmax - cmin); 223 res.b = 0.0; 224 } 225 res.g = s; 226 } 227 else 228 { 229 if (c.r == cmin) 230 { 231 res.g = ((c.g - cmin) * s) / (cmax - cmin); 232 res.r = 0.0; 233 } 234 else 235 { 236 res.r = ((c.r - cmin) * s) / (cmax - cmin); 237 res.g = 0.0; 238 } 239 res.b = s; 240 } 241 } 242 return res; 243} 244 245vec4 246color (vec4 Cs, vec4 Cb) 247{ 248 vec3 B = set_lum (Cs.rgb, lum (Cb.rgb)); 249 return composite (Cs, Cb, B); 250} 251 252vec4 253hue (vec4 Cs, vec4 Cb) 254{ 255 vec3 B = set_lum (set_sat (Cs.rgb, sat (Cb.rgb)), lum (Cb.rgb)); 256 return composite (Cs, Cb, B); 257} 258 259vec4 260saturation (vec4 Cs, vec4 Cb) 261{ 262 vec3 B = set_lum (set_sat (Cb.rgb, sat (Cs.rgb)), lum (Cb.rgb)); 263 return composite (Cs, Cb, B); 264} 265 266vec4 267luminosity (vec4 Cs, vec4 Cb) 268{ 269 vec3 B = set_lum (Cb.rgb, lum (Cs.rgb)); 270 return composite (Cs, Cb, B); 271} 272 273void main() { 274 vec4 bottom_color = GskTexture(u_source, vUv); 275 vec4 top_color = GskTexture(u_source2, vUv); 276 277 vec4 result; 278 if (u_mode == 0) 279 result = normal(top_color, bottom_color); 280 else if (u_mode == 1) 281 result = multiply(top_color, bottom_color); 282 else if (u_mode == 2) 283 result = screen(top_color, bottom_color); 284 else if (u_mode == 3) 285 result = overlay(top_color, bottom_color); 286 else if (u_mode == 4) 287 result = darken(top_color, bottom_color); 288 else if (u_mode == 5) 289 result = lighten(top_color, bottom_color); 290 else if (u_mode == 6) 291 result = color_dodge(top_color, bottom_color); 292 else if (u_mode == 7) 293 result = color_burn(top_color, bottom_color); 294 else if (u_mode == 8) 295 result = hard_light(top_color, bottom_color); 296 else if (u_mode == 9) 297 result = soft_light(top_color, bottom_color); 298 else if (u_mode == 10) 299 result = difference(top_color, bottom_color); 300 else if (u_mode == 11) 301 result = exclusion(top_color, bottom_color); 302 else if (u_mode == 12) 303 result = color(top_color, bottom_color); 304 else if (u_mode == 13) 305 result = hue(top_color, bottom_color); 306 else if (u_mode == 14) 307 result = saturation(top_color, bottom_color); 308 else if (u_mode == 15) 309 result = luminosity(top_color, bottom_color); 310 else 311 discard; 312 313 gskSetScaledOutputColor(result, u_alpha); 314} 315