GP: Correct Tonemapping for Blend Layers
[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 float blend_opacity;
12 uniform int tonemapping;
13
14 #define ON 1
15 #define OFF 0
16
17 #define MODE_NORMAL   0
18 #define MODE_OVERLAY  1
19 #define MODE_ADD      2
20 #define MODE_SUB      3
21 #define MODE_MULTIPLY 4
22 #define MODE_DIVIDE   5
23
24 float overlay_color(float a, float b)
25 {
26         float rtn;
27                 if (a < 0.5) {
28                         rtn = 2.0 * a * b;
29                 }
30                 else {
31                         rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
32                 }
33
34         return rtn;
35 }
36
37 vec4 get_blend_color(int mode, vec4 src_color, vec4 blend_color)
38 {
39         vec4 mix_color = blend_color;
40         vec4 outcolor;
41
42     if (mix_color.a == 0) {
43                 outcolor = src_color;
44         }
45         else if (mode == MODE_OVERLAY) {
46                 mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
47                 outcolor.r = overlay_color(src_color.r, mix_color.r);
48                 outcolor.g = overlay_color(src_color.g, mix_color.g);
49                 outcolor.b = overlay_color(src_color.b, mix_color.b);
50                 outcolor.a = src_color.a;
51         }
52         else if (mode == MODE_ADD){
53                 mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
54                 outcolor = src_color + mix_color;
55                 outcolor.a = src_color.a;
56         }
57         else if (mode == MODE_SUB){
58                 outcolor = src_color - mix_color;
59                 outcolor.a = clamp(src_color.a - (mix_color.a * blend_opacity), 0.0, 1.0);
60         }
61         else if (mode == MODE_MULTIPLY) {
62                 /* interpolate between 1 and color using opacity */
63                 mix_color.rgb = mix(vec3(1,1,1), mix_color.rgb * mix_color.a, blend_opacity);
64                 outcolor = src_color * mix_color;
65                 outcolor.a = src_color.a;
66         }
67         else if (mode == MODE_DIVIDE) {
68                 mix_color.rgb = mix_color.rgb * mix_color.a * blend_opacity;
69                 outcolor = src_color / mix_color;
70                 outcolor.a = src_color.a;
71         }
72         else {
73                 outcolor = mix_color * blend_opacity;;
74                 outcolor.a = src_color.a;
75         }
76         
77         return outcolor;
78 }
79
80 float linearrgb_to_srgb(float c)
81 {
82         if (c < 0.0031308)
83                 return (c < 0.0) ? 0.0 : c * 12.92;
84         else
85                 return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
86 }
87
88 vec4 tone(vec4 stroke_color)
89 {
90         if (tonemapping == 1) {
91                 vec4 color = vec4(0, 0, 0, stroke_color.a);
92                 color.r = linearrgb_to_srgb(stroke_color.r);
93                 color.g = linearrgb_to_srgb(stroke_color.g);
94                 color.b = linearrgb_to_srgb(stroke_color.b);
95                 return color;
96         }
97         else {
98                 return stroke_color;
99         }
100 }               
101
102 void main()
103 {
104         vec4 outcolor;
105         ivec2 uv = ivec2(gl_FragCoord.xy);
106         vec4 stroke_color =  texelFetch(strokeColor, uv, 0).rgba;
107         float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
108         
109         vec4 mix_color =  texelFetch(blendColor, uv, 0).rgba;
110         float mix_depth = texelFetch(blendDepth, uv, 0).r;
111
112         /* premult alpha factor to remove double blend effects */
113         if (stroke_color.a > 0) {
114                 stroke_color = vec4(vec3(stroke_color.rgb / stroke_color.a), stroke_color.a);
115         }
116         if (mix_color.a > 0) {
117                 mix_color = vec4(vec3(mix_color.rgb / mix_color.a), mix_color.a);
118         }
119         
120         /* Normal mode */
121         if (mode == MODE_NORMAL) {
122                 if (stroke_color.a > 0) {
123                         if (mix_color.a > 0) {
124                                 FragColor = vec4(mix(stroke_color.rgb, mix_color.rgb, mix_color.a), stroke_color.a);
125                                 gl_FragDepth = mix_depth;
126                         }
127                         else {
128                                 FragColor = stroke_color;
129                                 gl_FragDepth = stroke_depth;
130                         }
131                 }
132                 else {
133                         if (clamp_layer == ON) {
134                                 discard;
135                         }
136                         else {
137                                 FragColor = mix_color;
138                                 gl_FragDepth = mix_depth;
139                         }
140                 }
141                 FragColor = tone(FragColor);
142                 return;
143         }
144         
145         /* if not using mask, return mix color */
146         if ((stroke_color.a == 0) && (clamp_layer == OFF)) {
147                 FragColor = tone(mix_color);
148                 gl_FragDepth = mix_depth;
149                 return;
150         }
151
152         /* apply blend mode */
153         FragColor = tone(get_blend_color(mode, stroke_color, mix_color));
154         gl_FragDepth = stroke_depth;
155 }