3dc1f379f716d934ca8d2400770082ed58573b3b
[blender.git] / source / blender / draw / engines / gpencil / shaders / gpencil_blend_frag.glsl
1 in vec4 uvcoordsvar;
2
3 out vec4 FragColor;
4
5 uniform sampler2D strokeColor;
6 uniform sampler2D strokeDepth;
7 uniform sampler2D blendColor;
8 uniform sampler2D blendDepth;
9 uniform int mode;
10 uniform int clamp_layer;
11 uniform int tonemapping;
12
13 #define ON 1
14 #define OFF 0
15
16 #define MODE_REGULAR 0
17 #define MODE_OVERLAY 1
18 #define MODE_ADD 2
19 #define MODE_SUB 3
20 #define MODE_MULTIPLY 4
21 #define MODE_DIVIDE 5
22
23 float overlay_color(float a, float b)
24 {
25   float rtn;
26   if (a < 0.5) {
27     rtn = 2.0 * a * b;
28   }
29   else {
30     rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
31   }
32
33   return rtn;
34 }
35
36 vec4 get_blend_color(int mode, vec4 src_color, vec4 mix_color)
37 {
38   vec4 outcolor;
39
40   if (mix_color.a == 0) {
41     return src_color;
42   }
43
44   switch(mode)
45   {
46     case MODE_REGULAR:
47     {
48       /* premult */
49       src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
50       mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
51
52       outcolor = vec4(mix(src_color.rgb, mix_color.rgb, mix_color.a), src_color.a);
53       break;
54     }
55     case MODE_OVERLAY:
56     {
57       src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
58       mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
59
60       mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
61       outcolor.r = overlay_color(src_color.r, mix_color.r);
62       outcolor.g = overlay_color(src_color.g, mix_color.g);
63       outcolor.b = overlay_color(src_color.b, mix_color.b);
64       outcolor.a = src_color.a;
65       break;
66     }
67     case MODE_ADD:
68     {
69       mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
70       outcolor = src_color + mix_color;
71       outcolor.a = src_color.a;
72       break;
73     }
74     case MODE_SUB:
75     {
76       mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
77       outcolor = src_color - mix_color;
78       outcolor.a = clamp(src_color.a - mix_color.a, 0.0, 1.0);
79       break;
80     }
81     case MODE_MULTIPLY:
82     {
83       src_color = vec4(vec3(src_color.rgb / src_color.a), src_color.a);
84       mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
85
86       mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
87       outcolor = src_color * mix_color;
88       outcolor.a = src_color.a;
89       break;
90     }
91     case MODE_DIVIDE:
92     {
93       mix_color.rgb = mix(src_color.rgb, mix_color.rgb, mix_color.a);
94       outcolor = src_color / mix_color;
95       outcolor.a = src_color.a;
96       break;
97     }
98     default:
99     {
100       outcolor = mix_color;
101       outcolor.a = src_color.a;
102       break;
103     }
104   }
105   return clamp(outcolor, 0.0, 1.0);
106 }
107
108 float linearrgb_to_srgb(float c)
109 {
110   if (c < 0.0031308) {
111     return (c < 0.0) ? 0.0 : c * 12.92;
112   }
113   else {
114     return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
115   }
116 }
117
118 vec4 tone(vec4 stroke_color)
119 {
120   if (tonemapping == 1) {
121     vec4 color = vec4(0, 0, 0, stroke_color.a);
122     color.r = linearrgb_to_srgb(stroke_color.r);
123     color.g = linearrgb_to_srgb(stroke_color.g);
124     color.b = linearrgb_to_srgb(stroke_color.b);
125     return color;
126   }
127   else {
128     return stroke_color;
129   }
130 }
131
132 void main()
133 {
134   vec4 outcolor;
135   ivec2 uv = ivec2(gl_FragCoord.xy);
136   vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
137   float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
138
139   vec4 mix_color = texelFetch(blendColor, uv, 0).rgba;
140   float mix_depth = texelFetch(blendDepth, uv, 0).r;
141
142   if (stroke_color.a > 0) {
143     if (mix_color.a > 0) {
144       /* apply blend mode */
145       FragColor = get_blend_color(mode, stroke_color, mix_color);
146     }
147     else {
148       FragColor = stroke_color;
149     }
150     gl_FragDepth = min(stroke_depth, mix_depth);
151   }
152   else {
153     if (clamp_layer == ON) {
154       discard;
155     }
156     else {
157       /* if not using mask, return mix color */
158       FragColor = mix_color;
159       gl_FragDepth = mix_depth;
160     }
161   }
162
163   /* apply tone mapping */
164   FragColor = tone(FragColor);
165 }