diff options
Diffstat (limited to 'source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl')
-rw-r--r-- | source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl | 178 |
1 files changed, 46 insertions, 132 deletions
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl index 85dee4390a5..240d2091a51 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_blend_frag.glsl @@ -1,17 +1,6 @@ -in vec4 uvcoordsvar; - -out vec4 FragColor; uniform sampler2D strokeColor; -uniform sampler2D strokeDepth; -uniform sampler2D blendColor; -uniform sampler2D blendDepth; uniform int mode; -uniform int mask_layer; -uniform int tonemapping; - -#define ON 1 -#define OFF 0 #define MODE_REGULAR 0 #define MODE_OVERLAY 1 @@ -20,138 +9,63 @@ uniform int tonemapping; #define MODE_MULTIPLY 4 #define MODE_DIVIDE 5 -float overlay_color(float a, float b) -{ - float rtn; - if (a < 0.5) { - rtn = 2.0 * a * b; - } - else { - rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b); - } - - return rtn; -} +/* Blend equation is : FragColor0 + FragColor1 * DstColor */ +layout(location = 0, index = 0) out vec4 FragColor0; +layout(location = 0, index = 1) out vec4 FragColor1; -vec4 get_blend_color(int mode, vec4 src_color, vec4 mix_color) +void main() { - vec4 outcolor; - - if (mix_color.a == 0) { - return src_color; - } + ivec2 texel = ivec2(gl_FragCoord.xy); + vec4 src = texelFetch(strokeColor, texel, 0).rgba; switch (mode) { - case MODE_REGULAR: { - /* premult */ - src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a); - mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a); - - outcolor = vec4(mix(src_color.rgb, mix_color.rgb, mix_color.a), src_color.a); + case MODE_REGULAR: + FragColor0 = src; + FragColor1 = 1.0 - vec4(src.a); break; - } - case MODE_OVERLAY: { - src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a); - mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a); - - mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a); - outcolor.r = overlay_color(src_color.r, mix_color.r); - outcolor.g = overlay_color(src_color.g, mix_color.g); - outcolor.b = overlay_color(src_color.b, mix_color.b); - outcolor.a = src_color.a; + case MODE_OVERLAY: + /* Original overlay is : + * overlay = (a < 0.5) ? (2 * a * b) : (1 - 2 * (1 - a) * (1 - b)); + * But we are using dual source blending. So we need to rewrite it as a function of b (DST). + * overlay = 1 - 2 * (1 - a) * (1 - b); + * overlay = 1 + (2 * a - 2) * (1 - b); + * overlay = 1 + (2 * a - 2) - (2 * a - 2) * b; + * overlay = (2 * a - 1) + (2 - 2 * a) * b; + * + * With the right coefficient, we can get the 2 * a * b from the same equation. + * q0 = 0, q1 = -1; + * overlay = (2 * a - 1) * q0 + (2 * q0 - 2 * q1 * a) * b; + * overlay = 2 * a * b; + * */ + src.rgb = mix(vec3(0.5), src.rgb, src.a); + vec3 q0 = vec3(greaterThanEqual(src.rgb, vec3(0.5))); + vec3 q1 = q0 * 2.0 - 1.0; + vec3 src2 = 2.0 * src.rgb; + FragColor0.rgb = src2 * q0 - q0; + FragColor1.rgb = 2.0 * q0 - src2 * q1; break; - } - case MODE_ADD: { - mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a); - outcolor = src_color + mix_color; - outcolor.a = src_color.a; + case MODE_ADD: + FragColor0.rgb = src.rgb * src.a; + FragColor1.rgb = vec3(1.0); break; - } - case MODE_SUB: { - mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a); - outcolor = src_color - mix_color; - outcolor.a = clamp(src_color.a - mix_color.a, 0.0, 1.0); + case MODE_SUB: + FragColor0.rgb = -src.rgb * src.a; + FragColor1.rgb = vec3(1.0); break; - } - case MODE_MULTIPLY: { - src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a); - mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a); - - mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a); - outcolor = src_color * mix_color; - outcolor.a = src_color.a; + case MODE_MULTIPLY: + FragColor0.rgb = vec3(0.0); + FragColor1.rgb = mix(vec3(1.0), src.rgb, src.a); break; - } - case MODE_DIVIDE: { - mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a); - outcolor = src_color / mix_color; - outcolor.a = src_color.a; + case MODE_DIVIDE: + FragColor0.rgb = vec3(0.0); + FragColor1.rgb = 1.0 / mix(vec3(1.0), src.rgb, src.a); break; - } - default: { - outcolor = mix_color; - outcolor.a = src_color.a; + default: + FragColor0 = vec4(0.0); + FragColor1 = vec4(1.0); break; - } - } - return clamp(outcolor, 0.0, 1.0); -} - -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308) { - return (c < 0.0) ? 0.0 : c * 12.92; - } - else { - return 1.055 * pow(c, 1.0 / 2.4) - 0.055; - } -} - -vec4 tone(vec4 stroke_color) -{ - if (tonemapping == 1) { - vec4 color = vec4(0, 0, 0, stroke_color.a); - color.r = linearrgb_to_srgb(stroke_color.r); - color.g = linearrgb_to_srgb(stroke_color.g); - color.b = linearrgb_to_srgb(stroke_color.b); - return color; - } - else { - return stroke_color; - } -} - -void main() -{ - vec4 outcolor; - ivec2 uv = ivec2(gl_FragCoord.xy); - vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba; - float stroke_depth = texelFetch(strokeDepth, uv, 0).r; - - vec4 mix_color = texelFetch(blendColor, uv, 0).rgba; - float mix_depth = texelFetch(blendDepth, uv, 0).r; - - if (stroke_color.a > 0) { - if (mix_color.a > 0) { - /* apply blend mode */ - FragColor = get_blend_color(mode, stroke_color, mix_color); - } - else { - FragColor = stroke_color; - } - gl_FragDepth = min(stroke_depth, mix_depth); - } - else { - if (mask_layer == ON) { - discard; - } - else { - /* if not using mask, return mix color */ - FragColor = mix_color; - gl_FragDepth = mix_depth; - } } - /* apply tone mapping */ - FragColor = tone(FragColor); + FragColor0.a = 1.0 - clamp(dot(vec3(1.0 / 3.0), FragColor1.rgb), 0.0, 1.0); + FragColor1.a = 1.0 - FragColor0.a; } |