[[vertex]] uniform mat4 mvp; in vec4 pos; in vec2 uvs; in vec2 uvs2; out vec2 uv; out vec2 uv_2; out float q; void main() { uv = uvs; uv_2 = uvs2; q = pos.w; gl_Position = mvp * vec4(pos.xy, 0.0, 1.0); } [[fragment]] #include "include/ext-fb-fetch.glsl" #include "include/rand.glsl" #include "include/color.glsl" #include "include/blend-stroke.glsl" uniform sampler2D tex; uniform sampler2D tex_bg; uniform sampler2D tex_mix; uniform highp vec4 col; uniform highp vec2 resolution; uniform highp float alpha; uniform highp float opacity; uniform highp float noise; uniform highp float mix_alpha; uniform highp float wet; uniform bool use_pattern; uniform sampler2D tex_pattern; uniform highp vec2 pattern_scale; uniform highp float pattern_bright; uniform highp float pattern_contr; uniform highp float pattern_depth; uniform highp vec2 pattern_offset; uniform bool pattern_invert; uniform int patt_blend_mode; in highp vec2 uv; in highp vec2 uv_2; in highp float q; #if defined(GL_EXT_shader_framebuffer_fetch) inout highp vec4 frag; #else out highp vec4 frag; #endif void main() { highp vec2 uv2 = gl_FragCoord.st / resolution; highp float brush_alpha = ( 1.0 - texture(tex, uv/q).r ) * alpha; highp vec4 fg = vec4(col.rgb, brush_alpha); // early discard // if (fg.a == 0.0) // discard; if (use_pattern) { highp vec2 rscale = resolution / vec2(512.0); highp float patt = texture(tex_pattern, uv2 * (1.0 / pattern_scale) * rscale + pattern_offset).r; if (pattern_invert) patt = 1.0 - patt; patt = patt * pattern_depth + (1.0 - pattern_depth); if (pattern_bright != 0.5) patt = brightness1(patt, 1.0 - pattern_bright); if (pattern_contr != 0.5) patt = contrast1(patt, pattern_contr); fg.a = blend_stroke(fg.a, patt, pattern_depth, patt_blend_mode); } #if defined(GL_EXT_shader_framebuffer_fetch) highp vec4 bg = frag; #elif defined(GL_ARM_shader_framebuffer_fetch) highp vec4 bg = gl_LastFragColorARM; #else highp vec4 bg = texture(tex_bg, uv2); #endif if (bg.a == 0.0) bg.rgb = col.rgb; fg.a *= 1.0-rand(uv2+uv)*noise; // no need to go further // if (fg.a <= 0.0) // discard; if (mix_alpha > 0.0) { highp vec2 uv_mix = uv_2 / q; if (uv_mix.x < 0.0 || uv_mix.x > 1.0 || uv_mix.y < 0.0 || uv_mix.y > 1.0) discard; highp vec4 mbg = texture(tex_mix, uv_mix); fg.rgb = mix(fg.rgb, mbg.rgb, mix_alpha * mbg.a); } highp float contribution = max(0.0, opacity - bg.a) * fg.a; highp float alpha_tot = bg.a + contribution; highp vec3 rgb = mix(bg.rgb, fg.rgb, clamp(fg.a / alpha_tot, 0.0, 1.0)); highp vec4 frag_wet = vec4(rgb, max(bg.a, fg.a * 1.2)); highp vec4 frag_dry = vec4(rgb, alpha_tot); frag = mix(frag_dry, frag_wet, wet); }