Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.glsl178
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;
}