Files
panopainter/data/shaders/stroke.glsl
2019-12-02 17:36:00 +01:00

114 lines
2.9 KiB
GLSL

[[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 = clamp(blend_stroke(fg.a, patt, pattern_depth, patt_blend_mode), 0.0, 1.0);
}
#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);
}