Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / draw / engines / gpencil / gpencil_shader_fx.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2017, Blender Foundation.
17  */
18
19 /** \file \ingroup draw
20  */
21 #include "DNA_gpencil_types.h"
22 #include "DNA_shader_fx_types.h"
23 #include "DNA_view3d_types.h"
24 #include "DNA_camera_types.h"
25
26 #include "BKE_gpencil.h"
27
28 #include "DRW_render.h"
29
30 #include "BKE_camera.h"
31
32 #include "gpencil_engine.h"
33
34 extern char datatoc_gpencil_fx_blur_frag_glsl[];
35 extern char datatoc_gpencil_fx_colorize_frag_glsl[];
36 extern char datatoc_gpencil_fx_flip_frag_glsl[];
37 extern char datatoc_gpencil_fx_light_frag_glsl[];
38 extern char datatoc_gpencil_fx_pixel_frag_glsl[];
39 extern char datatoc_gpencil_fx_rim_prepare_frag_glsl[];
40 extern char datatoc_gpencil_fx_rim_resolve_frag_glsl[];
41 extern char datatoc_gpencil_fx_shadow_prepare_frag_glsl[];
42 extern char datatoc_gpencil_fx_shadow_resolve_frag_glsl[];
43 extern char datatoc_gpencil_fx_glow_prepare_frag_glsl[];
44 extern char datatoc_gpencil_fx_glow_resolve_frag_glsl[];
45 extern char datatoc_gpencil_fx_swirl_frag_glsl[];
46 extern char datatoc_gpencil_fx_wave_frag_glsl[];
47
48 /* verify if this fx is active */
49 static bool effect_is_active(bGPdata *gpd, ShaderFxData *fx, bool is_render)
50 {
51         if (fx == NULL) {
52                 return false;
53         }
54
55         if (gpd == NULL) {
56                 return false;
57         }
58
59         bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
60         if (((fx->mode & eShaderFxMode_Editmode) == 0) && (is_edit)) {
61                 return false;
62         }
63
64         if (((fx->mode & eShaderFxMode_Realtime) && (is_render == false)) ||
65             ((fx->mode & eShaderFxMode_Render) && (is_render == true)))
66         {
67                 return true;
68         }
69
70         return false;
71 }
72
73 /**
74  * Get normal of draw using one stroke of visible layer
75  * \param gpd: GP datablock
76  * \param r_point: Point on plane
77  * \param r_normal: Normal vector
78  */
79 static bool get_normal_vector(bGPdata *gpd, float r_point[3], float r_normal[3])
80 {
81         for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
82                 if (gpl->flag & GP_LAYER_HIDE) {
83                         continue;
84                 }
85
86                 /* get frame  */
87                 bGPDframe *gpf = gpl->actframe;
88                 if (gpf == NULL) {
89                         continue;
90                 }
91                 for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
92                         if (gps->totpoints >= 3) {
93                                 bGPDspoint *pt = &gps->points[0];
94                                 BKE_gpencil_stroke_normal(gps, r_normal);
95                                 /* in some weird situations, the normal cannot be calculated, so try next stroke */
96                                 if ((r_normal[0] != 0.0f) || (r_normal[1] != 0.0f) || (r_normal[2] != 0.0f)) {
97                                         copy_v3_v3(r_point, &pt->x);
98                                         return true;
99                                 }
100                         }
101                 }
102         }
103
104         return false;
105 }
106
107 /* helper to get near and far depth of field values */
108 static void GPENCIL_dof_nearfar(Object *camera, float coc, float nearfar[2])
109 {
110         if (camera == NULL) {
111                 return;
112         }
113
114         const DRWContextState *draw_ctx = DRW_context_state_get();
115         Scene *scene = draw_ctx->scene;
116         Camera *cam = (Camera *)camera->data;
117
118         float fstop = cam->gpu_dof.fstop;
119         float focus_dist = BKE_camera_object_dof_distance(camera);
120         float focal_len = cam->lens;
121
122         /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
123          * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
124          * because the shader reads coordinates in world space, which is in blender units.
125          * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
126         float scale = (scene->unit.system) ? scene->unit.scale_length : 1.0f;
127         float scale_camera = 0.001f / scale;
128         /* we want radius here for the aperture number  */
129         float aperture_scaled = 0.5f * scale_camera * focal_len / fstop;
130         float focal_len_scaled = scale_camera * focal_len;
131
132         float hyperfocal = (focal_len_scaled * focal_len_scaled) / (aperture_scaled * coc);
133         nearfar[0] = (hyperfocal * focus_dist) / (hyperfocal + focal_len);
134         nearfar[1] = (hyperfocal * focus_dist) / (hyperfocal - focal_len);
135 }
136
137 /* ****************  Shader Effects ***************************** */
138
139 /* Gaussian Blur FX
140  * The effect is done using two shading groups because is faster to apply horizontal
141  * and vertical in different operations.
142  */
143 static void DRW_gpencil_fx_blur(
144         ShaderFxData *fx, int ob_idx, GPENCIL_e_data *e_data,
145         GPENCIL_Data *vedata, tGPencilObjectCache *cache)
146 {
147         if (fx == NULL) {
148                 return;
149         }
150
151         BlurShaderFxData *fxd = (BlurShaderFxData *)fx;
152
153         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
154         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
155         const DRWContextState *draw_ctx = DRW_context_state_get();
156         View3D *v3d = draw_ctx->v3d;
157         RegionView3D *rv3d = draw_ctx->rv3d;
158         DRWShadingGroup *fx_shgrp;
159         bGPdata *gpd = cache->gpd;
160         copy_v3_v3(fxd->runtime.loc, cache->loc);
161
162         fxd->blur[0] = fxd->radius[0];
163         fxd->blur[1] = fxd->radius[1];
164
165         /* init weight */
166         if (fxd->flag & FX_BLUR_DOF_MODE) {
167                 /* viewport and opengl render */
168                 Object *camera = NULL;
169                 if (rv3d) {
170                         if (rv3d->persp == RV3D_CAMOB) {
171                                 camera = v3d->camera;
172                         }
173                 }
174                 else {
175                         camera = stl->storage->camera;
176                 }
177
178                 if (camera) {
179                         float nearfar[2];
180                         GPENCIL_dof_nearfar(camera, fxd->coc, nearfar);
181                         float zdepth = stl->g_data->gp_object_cache[ob_idx].zdepth;
182                         /* the object is on focus area */
183                         if ((zdepth >= nearfar[0]) && (zdepth <= nearfar[1])) {
184                                 fxd->blur[0] = 0;
185                                 fxd->blur[1] = 0;
186                         }
187                         else {
188                                 float f;
189                                 if (zdepth < nearfar[0]) {
190                                         f = nearfar[0] - zdepth;
191                                 }
192                                 else {
193                                         f = zdepth - nearfar[1];
194                                 }
195                                 fxd->blur[0] = f;
196                                 fxd->blur[1] = f;
197                                 CLAMP2(&fxd->blur[0], 0, fxd->radius[0]);
198                         }
199                 }
200                 else {
201                         /* if not camera view, the blur is disabled */
202                         fxd->blur[0] = 0;
203                         fxd->blur[1] = 0;
204                 }
205         }
206
207         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
208
209         fx_shgrp = DRW_shgroup_create(
210                 e_data->gpencil_fx_blur_sh,
211                 psl->fx_shader_pass_blend);
212         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
213         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
214         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
215         DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
216         DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
217
218         DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
219         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
220         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
221
222         fxd->runtime.fx_sh = fx_shgrp;
223 }
224
225 /* Colorize FX */
226 static void DRW_gpencil_fx_colorize(
227         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
228 {
229         if (fx == NULL) {
230                 return;
231         }
232         ColorizeShaderFxData *fxd = (ColorizeShaderFxData *)fx;
233         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
234         DRWShadingGroup *fx_shgrp;
235
236         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
237         fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_colorize_sh, psl->fx_shader_pass);
238         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
239         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
240         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
241         DRW_shgroup_uniform_vec4(fx_shgrp, "low_color", &fxd->low_color[0], 1);
242         DRW_shgroup_uniform_vec4(fx_shgrp, "high_color", &fxd->high_color[0], 1);
243         DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
244         DRW_shgroup_uniform_float(fx_shgrp, "factor", &fxd->factor, 1);
245
246         fxd->runtime.fx_sh = fx_shgrp;
247 }
248
249 /* Flip FX */
250 static void DRW_gpencil_fx_flip(
251         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
252 {
253         if (fx == NULL) {
254                 return;
255         }
256         FlipShaderFxData *fxd = (FlipShaderFxData *)fx;
257         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
258         DRWShadingGroup *fx_shgrp;
259
260         fxd->flipmode = 100;
261         /* the number works as bit flag */
262         if (fxd->flag & FX_FLIP_HORIZONTAL) {
263                 fxd->flipmode += 10;
264         }
265         if (fxd->flag & FX_FLIP_VERTICAL) {
266                 fxd->flipmode += 1;
267         }
268
269         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
270         fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_flip_sh, psl->fx_shader_pass);
271         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
272         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
273         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
274         DRW_shgroup_uniform_int(fx_shgrp, "flipmode", &fxd->flipmode, 1);
275
276         DRW_shgroup_uniform_vec2(fx_shgrp, "wsize", DRW_viewport_size_get(), 1);
277
278         fxd->runtime.fx_sh = fx_shgrp;
279 }
280
281 /* Light FX */
282 static void DRW_gpencil_fx_light(
283         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
284         tGPencilObjectCache *cache)
285 {
286         if (fx == NULL) {
287                 return;
288         }
289         LightShaderFxData *fxd = (LightShaderFxData *)fx;
290
291         if (fxd->object == NULL) {
292                 return;
293         }
294         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
295         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
296         DRWShadingGroup *fx_shgrp;
297
298         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
299         fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_light_sh, psl->fx_shader_pass);
300         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
301         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
302         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
303
304         DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
305
306         /* location of the light using obj location as origin */
307         copy_v3_v3(fxd->loc, fxd->object->obmat[3]);
308
309         /* Calc distance to strokes plane
310          * The w component of location is used to transfer the distance to drawing plane
311          */
312         float r_point[3], r_normal[3];
313         float r_plane[4];
314         bGPdata *gpd = cache->gpd;
315         if (!get_normal_vector(gpd, r_point, r_normal)) {
316                 return;
317         }
318         mul_mat3_m4_v3(cache->obmat, r_normal); /* only rotation component */
319         plane_from_point_normal_v3(r_plane, r_point, r_normal);
320         float dt = dist_to_plane_v3(fxd->object->obmat[3], r_plane);
321         fxd->loc[3] = dt; /* use last element to save it */
322
323         DRW_shgroup_uniform_vec4(fx_shgrp, "loc", &fxd->loc[0], 1);
324
325         DRW_shgroup_uniform_float(fx_shgrp, "energy", &fxd->energy, 1);
326         DRW_shgroup_uniform_float(fx_shgrp, "ambient", &fxd->ambient, 1);
327
328         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
329         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
330
331         fxd->runtime.fx_sh = fx_shgrp;
332 }
333
334 /* Pixelate FX */
335 static void DRW_gpencil_fx_pixel(
336         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
337         tGPencilObjectCache *cache)
338 {
339         if (fx == NULL) {
340                 return;
341         }
342         PixelShaderFxData *fxd = (PixelShaderFxData *)fx;
343
344         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
345         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
346         DRWShadingGroup *fx_shgrp;
347         bGPdata *gpd = cache->gpd;
348         copy_v3_v3(fxd->runtime.loc, cache->loc);
349
350         fxd->size[2] = (int)fxd->flag & FX_PIXEL_USE_LINES;
351
352         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
353         fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_pixel_sh, psl->fx_shader_pass);
354         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
355         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
356         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
357         DRW_shgroup_uniform_int(fx_shgrp, "size", &fxd->size[0], 3);
358         DRW_shgroup_uniform_vec4(fx_shgrp, "color", &fxd->rgba[0], 1);
359
360         DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
361         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
362         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
363
364         fxd->runtime.fx_sh = fx_shgrp;
365 }
366
367 /* Rim FX */
368 static void DRW_gpencil_fx_rim(
369         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
370         tGPencilObjectCache *cache)
371 {
372         if (fx == NULL) {
373                 return;
374         }
375         RimShaderFxData *fxd = (RimShaderFxData *)fx;
376         bGPdata *gpd = cache->gpd;
377
378         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
379         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
380         DRWShadingGroup *fx_shgrp;
381
382         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
383         copy_v3_v3(fxd->runtime.loc, cache->loc);
384
385         /* prepare pass */
386         fx_shgrp = DRW_shgroup_create(
387                 e_data->gpencil_fx_rim_prepare_sh,
388                 psl->fx_shader_pass_blend);
389         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
390         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
391         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
392         DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
393
394         DRW_shgroup_uniform_int(fx_shgrp, "offset", &fxd->offset[0], 2);
395         DRW_shgroup_uniform_vec3(fx_shgrp, "rim_color", &fxd->rim_rgb[0], 1);
396         DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1);
397
398         DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
399         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
400         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
401
402         fxd->runtime.fx_sh = fx_shgrp;
403
404         /* blur pass */
405         fx_shgrp = DRW_shgroup_create(
406                 e_data->gpencil_fx_blur_sh,
407                 psl->fx_shader_pass_blend);
408         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
409         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
410         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
411         DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
412         DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
413
414         DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
415         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
416         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
417
418         fxd->runtime.fx_sh_b = fx_shgrp;
419
420         /* resolve pass */
421         fx_shgrp = DRW_shgroup_create(
422                 e_data->gpencil_fx_rim_resolve_sh,
423                 psl->fx_shader_pass_blend);
424         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
425         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
426         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
427         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeRim", &e_data->temp_color_tx_fx);
428         DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1);
429         DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
430
431         fxd->runtime.fx_sh_c = fx_shgrp;
432 }
433
434 /* Shadow FX */
435 static void DRW_gpencil_fx_shadow(
436         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
437         tGPencilObjectCache *cache)
438 {
439         if (fx == NULL) {
440                 return;
441         }
442         ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
443         if ((!fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT)) {
444                 fxd->runtime.fx_sh = NULL;
445                 fxd->runtime.fx_sh_b = NULL;
446                 fxd->runtime.fx_sh_c = NULL;
447                 return;
448         }
449
450         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
451         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
452         DRWShadingGroup *fx_shgrp;
453         bGPdata *gpd = cache->gpd;
454         copy_v3_v3(fxd->runtime.loc, cache->loc);
455
456         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
457         /* prepare pass */
458         fx_shgrp = DRW_shgroup_create(
459                 e_data->gpencil_fx_shadow_prepare_sh,
460                 psl->fx_shader_pass_blend);
461         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
462         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
463         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
464         DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
465
466         DRW_shgroup_uniform_int(fx_shgrp, "offset", &fxd->offset[0], 2);
467         DRW_shgroup_uniform_float(fx_shgrp, "scale", &fxd->scale[0], 2);
468         DRW_shgroup_uniform_float(fx_shgrp, "rotation", &fxd->rotation, 1);
469         DRW_shgroup_uniform_vec4(fx_shgrp, "shadow_color", &fxd->shadow_rgba[0], 1);
470
471         if ((fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT)) {
472                 DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->object->obmat[3], 1);
473         }
474         else {
475                 DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
476         }
477
478         const int nowave = -1;
479         if (fxd->flag & FX_SHADOW_USE_WAVE) {
480                 DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1);
481         }
482         else {
483                 DRW_shgroup_uniform_int(fx_shgrp, "orientation", &nowave, 1);
484         }
485         DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
486         DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1);
487         DRW_shgroup_uniform_float(fx_shgrp, "phase", &fxd->phase, 1);
488
489         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
490         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
491
492         fxd->runtime.fx_sh = fx_shgrp;
493
494         /* blur pass */
495         fx_shgrp = DRW_shgroup_create(
496                 e_data->gpencil_fx_blur_sh,
497                 psl->fx_shader_pass_blend);
498         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
499         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
500         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
501         DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
502         DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
503
504         DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
505         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
506         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
507
508         fxd->runtime.fx_sh_b = fx_shgrp;
509
510         /* resolve pass */
511         fx_shgrp = DRW_shgroup_create(
512                 e_data->gpencil_fx_shadow_resolve_sh,
513                 psl->fx_shader_pass_blend);
514         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
515         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
516         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
517         DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowColor", &e_data->temp_color_tx_fx);
518         DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowDepth", &e_data->temp_depth_tx_fx);
519
520         fxd->runtime.fx_sh_c = fx_shgrp;
521 }
522
523 /* Glow FX */
524 static void DRW_gpencil_fx_glow(
525         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
526         tGPencilObjectCache *cache)
527 {
528         if (fx == NULL) {
529                 return;
530         }
531         GlowShaderFxData *fxd = (GlowShaderFxData *)fx;
532         bGPdata *gpd = cache->gpd;
533         copy_v3_v3(fxd->runtime.loc, cache->loc);
534
535         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
536         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
537         DRWShadingGroup *fx_shgrp;
538
539         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
540         /* prepare pass */
541         fx_shgrp = DRW_shgroup_create(
542                 e_data->gpencil_fx_glow_prepare_sh,
543                 psl->fx_shader_pass_blend);
544         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
545         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
546         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
547
548         DRW_shgroup_uniform_vec3(fx_shgrp, "glow_color", &fxd->glow_color[0], 1);
549         DRW_shgroup_uniform_vec3(fx_shgrp, "select_color", &fxd->select_color[0], 1);
550         DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
551         DRW_shgroup_uniform_float(fx_shgrp, "threshold", &fxd->threshold, 1);
552
553         fxd->runtime.fx_sh = fx_shgrp;
554
555         /* blur pass */
556         fx_shgrp = DRW_shgroup_create(
557                 e_data->gpencil_fx_blur_sh,
558                 psl->fx_shader_pass_blend);
559         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
560         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
561         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
562         DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
563         DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
564
565         DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1);
566         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
567         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
568
569         fxd->runtime.fx_sh_b = fx_shgrp;
570
571         /* resolve pass */
572         fx_shgrp = DRW_shgroup_create(
573                 e_data->gpencil_fx_glow_resolve_sh,
574                 psl->fx_shader_pass_blend);
575         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
576         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
577         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
578         DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowColor", &e_data->temp_color_tx_fx);
579         DRW_shgroup_uniform_texture_ref(fx_shgrp, "glowDepth", &e_data->temp_depth_tx_fx);
580
581         /* reuse field */
582         DRW_shgroup_uniform_int(fx_shgrp, "alpha_mode", &fxd->blur[1], 1);
583
584         fxd->runtime.fx_sh_c = fx_shgrp;
585 }
586
587 /* Swirl FX */
588 static void DRW_gpencil_fx_swirl(
589         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
590         tGPencilObjectCache *cache)
591 {
592         if (fx == NULL) {
593                 return;
594         }
595         SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
596         if (fxd->object == NULL) {
597                 return;
598         }
599
600         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
601         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
602         DRWShadingGroup *fx_shgrp;
603         bGPdata *gpd = cache->gpd;
604
605         fxd->transparent = (int)fxd->flag & FX_SWIRL_MAKE_TRANSPARENT;
606
607         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
608         fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_swirl_sh, psl->fx_shader_pass);
609         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
610         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
611         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
612
613         DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
614
615         DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->object->obmat[3], 1);
616
617         DRW_shgroup_uniform_int(fx_shgrp, "radius", &fxd->radius, 1);
618         DRW_shgroup_uniform_float(fx_shgrp, "angle", &fxd->angle, 1);
619         DRW_shgroup_uniform_int(fx_shgrp, "transparent", &fxd->transparent, 1);
620
621         DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
622         DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
623
624         fxd->runtime.fx_sh = fx_shgrp;
625 }
626
627 /* Wave Distorsion FX */
628 static void DRW_gpencil_fx_wave(
629         ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata)
630 {
631         if (fx == NULL) {
632                 return;
633         }
634
635         WaveShaderFxData *fxd = (WaveShaderFxData *)fx;
636
637         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
638         GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
639
640         DRWShadingGroup *fx_shgrp = DRW_shgroup_create(e_data->gpencil_fx_wave_sh, psl->fx_shader_pass);
641         DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
642         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
643         DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
644         DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
645         DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1);
646         DRW_shgroup_uniform_float(fx_shgrp, "phase", &fxd->phase, 1);
647         DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1);
648         DRW_shgroup_uniform_vec2(fx_shgrp, "wsize", DRW_viewport_size_get(), 1);
649
650         fxd->runtime.fx_sh = fx_shgrp;
651 }
652
653 /* ************************************************************** */
654
655 /* create all FX shaders */
656 void GPENCIL_create_fx_shaders(GPENCIL_e_data *e_data)
657 {
658         /* fx shaders (all in screen space) */
659         if (!e_data->gpencil_fx_blur_sh) {
660                 e_data->gpencil_fx_blur_sh = DRW_shader_create_fullscreen(
661                         datatoc_gpencil_fx_blur_frag_glsl, NULL);
662         }
663         if (!e_data->gpencil_fx_colorize_sh) {
664                 e_data->gpencil_fx_colorize_sh = DRW_shader_create_fullscreen(
665                         datatoc_gpencil_fx_colorize_frag_glsl, NULL);
666         }
667         if (!e_data->gpencil_fx_flip_sh) {
668                 e_data->gpencil_fx_flip_sh = DRW_shader_create_fullscreen(
669                         datatoc_gpencil_fx_flip_frag_glsl, NULL);
670         }
671         if (!e_data->gpencil_fx_light_sh) {
672                 e_data->gpencil_fx_light_sh = DRW_shader_create_fullscreen(
673                         datatoc_gpencil_fx_light_frag_glsl, NULL);
674         }
675         if (!e_data->gpencil_fx_pixel_sh) {
676                 e_data->gpencil_fx_pixel_sh = DRW_shader_create_fullscreen(
677                         datatoc_gpencil_fx_pixel_frag_glsl, NULL);
678         }
679         if (!e_data->gpencil_fx_rim_prepare_sh) {
680                 e_data->gpencil_fx_rim_prepare_sh = DRW_shader_create_fullscreen(
681                         datatoc_gpencil_fx_rim_prepare_frag_glsl, NULL);
682
683                 e_data->gpencil_fx_rim_resolve_sh = DRW_shader_create_fullscreen(
684                         datatoc_gpencil_fx_rim_resolve_frag_glsl, NULL);
685         }
686         if (!e_data->gpencil_fx_shadow_prepare_sh) {
687                 e_data->gpencil_fx_shadow_prepare_sh = DRW_shader_create_fullscreen(
688                         datatoc_gpencil_fx_shadow_prepare_frag_glsl, NULL);
689
690                 e_data->gpencil_fx_shadow_resolve_sh = DRW_shader_create_fullscreen(
691                         datatoc_gpencil_fx_shadow_resolve_frag_glsl, NULL);
692         }
693         if (!e_data->gpencil_fx_glow_prepare_sh) {
694                 e_data->gpencil_fx_glow_prepare_sh = DRW_shader_create_fullscreen(
695                         datatoc_gpencil_fx_glow_prepare_frag_glsl, NULL);
696
697                 e_data->gpencil_fx_glow_resolve_sh = DRW_shader_create_fullscreen(
698                         datatoc_gpencil_fx_glow_resolve_frag_glsl, NULL);
699         }
700         if (!e_data->gpencil_fx_swirl_sh) {
701                 e_data->gpencil_fx_swirl_sh = DRW_shader_create_fullscreen(
702                         datatoc_gpencil_fx_swirl_frag_glsl, NULL);
703         }
704         if (!e_data->gpencil_fx_wave_sh) {
705                 e_data->gpencil_fx_wave_sh = DRW_shader_create_fullscreen(
706                         datatoc_gpencil_fx_wave_frag_glsl, NULL);
707         }
708 }
709
710 /* free FX shaders */
711 void GPENCIL_delete_fx_shaders(GPENCIL_e_data *e_data)
712 {
713         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_blur_sh);
714         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_colorize_sh);
715         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_flip_sh);
716         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_light_sh);
717         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_pixel_sh);
718         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_prepare_sh);
719         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_resolve_sh);
720         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_prepare_sh);
721         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_resolve_sh);
722         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_prepare_sh);
723         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_glow_resolve_sh);
724         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_swirl_sh);
725         DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_wave_sh);
726 }
727
728 /* create all passes used by FX */
729 void GPENCIL_create_fx_passes(GPENCIL_PassList *psl)
730 {
731         psl->fx_shader_pass = DRW_pass_create(
732                 "GPencil Shader FX Pass",
733                 DRW_STATE_WRITE_COLOR |
734                 DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
735         psl->fx_shader_pass_blend = DRW_pass_create(
736                 "GPencil Shader FX Pass",
737                 DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND |
738                 DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
739 }
740
741
742 /* prepare fx shading groups */
743 void DRW_gpencil_fx_prepare(
744         GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
745         tGPencilObjectCache *cache)
746 {
747         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
748         int ob_idx = cache->idx;
749
750         if (cache->shader_fx.first == NULL) {
751                 return;
752         }
753         /* loop FX */
754         for (ShaderFxData *fx = cache->shader_fx.first; fx; fx = fx->next) {
755                 if (effect_is_active(cache->gpd, fx, stl->storage->is_render)) {
756                         switch (fx->type) {
757                                 case eShaderFxType_Blur:
758                                         DRW_gpencil_fx_blur(fx, ob_idx, e_data, vedata, cache);
759                                         break;
760                                 case eShaderFxType_Colorize:
761                                         DRW_gpencil_fx_colorize(fx, e_data, vedata);
762                                         break;
763                                 case eShaderFxType_Flip:
764                                         DRW_gpencil_fx_flip(fx, e_data, vedata);
765                                         break;
766                                 case eShaderFxType_Light:
767                                         DRW_gpencil_fx_light(fx, e_data, vedata, cache);
768                                         break;
769                                 case eShaderFxType_Pixel:
770                                         DRW_gpencil_fx_pixel(fx, e_data, vedata, cache);
771                                         break;
772                                 case eShaderFxType_Rim:
773                                         DRW_gpencil_fx_rim(fx, e_data, vedata, cache);
774                                         break;
775                                 case eShaderFxType_Shadow:
776                                         DRW_gpencil_fx_shadow(fx, e_data, vedata, cache);
777                                         break;
778                                 case eShaderFxType_Glow:
779                                         DRW_gpencil_fx_glow(fx, e_data, vedata, cache);
780                                         break;
781                                 case eShaderFxType_Swirl:
782                                         DRW_gpencil_fx_swirl(fx, e_data, vedata, cache);
783                                         break;
784                                 case eShaderFxType_Wave:
785                                         DRW_gpencil_fx_wave(fx, e_data, vedata);
786                                         break;
787                                 default:
788                                         break;
789                         }
790                 }
791         }
792
793 }
794
795 /* helper to draw one FX pass and do ping-pong copy */
796 static void gpencil_draw_fx_pass(
797         GPENCIL_e_data *e_data,
798         GPENCIL_PassList *psl,
799         GPENCIL_FramebufferList *fbl,
800         DRWShadingGroup *shgrp, bool blend)
801 {
802         if (shgrp == NULL) {
803                 return;
804         }
805
806         const float clearcol[4] = {0.0f};
807         GPU_framebuffer_bind(fbl->temp_fb_b);
808         GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
809
810         /* draw effect pass in temp texture (B) using as source the previous image
811          * existing in the other temp texture (A) */
812         if (!blend) {
813                 DRW_draw_pass_subset(psl->fx_shader_pass, shgrp, shgrp);
814         }
815         else {
816                 DRW_draw_pass_subset(psl->fx_shader_pass_blend, shgrp, shgrp);
817         }
818
819         /* copy pass from b to a for ping-pong frame buffers */
820         e_data->input_depth_tx = e_data->temp_depth_tx_b;
821         e_data->input_color_tx = e_data->temp_color_tx_b;
822
823         GPU_framebuffer_bind(fbl->temp_fb_a);
824         GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
825         DRW_draw_pass(psl->mix_pass_noblend);
826 }
827
828 /* helper to manage gaussian blur passes */
829 static void draw_gpencil_blur_passes(
830         GPENCIL_e_data *e_data,
831         GPENCIL_Data *vedata,
832         BlurShaderFxData *fxd)
833 {
834         if (fxd->runtime.fx_sh == NULL) {
835                 return;
836         }
837
838         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
839         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
840         DRWShadingGroup *shgrp = fxd->runtime.fx_sh;
841         int samples = fxd->samples;
842
843         float bx = fxd->blur[0];
844         float by = fxd->blur[1];
845
846         /* the blur is done in two steps (Hor/Ver) because is faster and
847          * gets better result
848          *
849          * samples could be 0 and disable de blur effects because sometimes
850          * is easier animate the number of samples only, instead to animate the
851          * hide/unhide and the number of samples to make some effects.
852          */
853         for (int b = 0; b < samples; b++) {
854                 /* horizontal */
855                 if (bx > 0) {
856                         fxd->blur[0] = bx;
857                         fxd->blur[1] = 0;
858                         gpencil_draw_fx_pass(e_data, psl, fbl, shgrp, true);
859                 }
860                 /* vertical */
861                 if (by > 0) {
862                         fxd->blur[0] = 0;
863                         fxd->blur[1] = by;
864                         gpencil_draw_fx_pass(e_data, psl, fbl, shgrp, true);
865                 }
866         }
867 }
868
869 /* blur intermediate pass */
870 static void draw_gpencil_midpass_blur(
871         GPENCIL_Data *vedata,
872         ShaderFxData_Runtime *runtime)
873 {
874         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
875         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
876         const float clearcol[4] = {0.0f};
877
878         GPU_framebuffer_bind(fbl->temp_fb_b);
879         GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
880         DRW_draw_pass_subset(psl->fx_shader_pass_blend,
881                 runtime->fx_sh_b, runtime->fx_sh_b);
882
883         /* copy pass from b for ping-pong frame buffers */
884         GPU_framebuffer_bind(fbl->temp_fb_fx);
885         GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
886         DRW_draw_pass(psl->mix_pass_noblend);
887 }
888
889 /* do blur of mid passes */
890 static void draw_gpencil_do_blur(
891         GPENCIL_e_data *e_data,
892         GPENCIL_Data *vedata,
893         ShaderFxData_Runtime *runtime,
894         int samples, int bx, int by, int blur[2])
895 {
896         e_data->input_depth_tx = e_data->temp_depth_tx_b;
897         e_data->input_color_tx = e_data->temp_color_tx_b;
898
899         if ((samples > 0) && ((bx > 0) || (by > 0))) {
900                 for (int x = 0; x < samples; x++) {
901
902                         /* horizontal */
903                         blur[0] = bx;
904                         blur[1] = 0;
905                         draw_gpencil_midpass_blur(vedata, runtime);
906
907                         /* Vertical */
908                         blur[0] = 0;
909                         blur[1] = by;
910                         draw_gpencil_midpass_blur(vedata, runtime);
911
912                         blur[0] = bx;
913                         blur[1] = by;
914                 }
915         }
916 }
917
918 /* helper to draw RIM passes */
919 static void draw_gpencil_rim_passes(
920         GPENCIL_e_data *e_data,
921         GPENCIL_Data *vedata,
922         RimShaderFxData *fxd)
923 {
924         if (fxd->runtime.fx_sh_b == NULL) {
925                 return;
926         }
927
928         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
929         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
930
931         const float clearcol[4] = {0.0f};
932
933         /* prepare mask */
934         GPU_framebuffer_bind(fbl->temp_fb_fx);
935         GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
936         DRW_draw_pass_subset(
937                 psl->fx_shader_pass_blend,
938                 fxd->runtime.fx_sh, fxd->runtime.fx_sh);
939
940         /* blur rim */
941         draw_gpencil_do_blur(
942                 e_data, vedata, &fxd->runtime,
943                 fxd->samples,
944                 fxd->blur[0], fxd->blur[1],
945                 &fxd->blur[0]);
946
947         /* resolve */
948         GPU_framebuffer_bind(fbl->temp_fb_b);
949         GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
950         DRW_draw_pass_subset(
951                 psl->fx_shader_pass_blend,
952                 fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
953
954         /* copy pass from b to a for ping-pong frame buffers */
955         e_data->input_depth_tx = e_data->temp_depth_tx_b;
956         e_data->input_color_tx = e_data->temp_color_tx_b;
957
958         GPU_framebuffer_bind(fbl->temp_fb_a);
959         GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
960         DRW_draw_pass(psl->mix_pass_noblend);
961 }
962
963 /* helper to draw SHADOW passes */
964 static void draw_gpencil_shadow_passes(
965         GPENCIL_e_data *e_data,
966         GPENCIL_Data *vedata,
967         ShadowShaderFxData *fxd)
968 {
969         if (fxd->runtime.fx_sh_b == NULL) {
970                 return;
971         }
972
973         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
974         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
975         const float clearcol[4] = {0.0f};
976
977         /* prepare shadow */
978         GPU_framebuffer_bind(fbl->temp_fb_fx);
979         GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
980         DRW_draw_pass_subset(
981                 psl->fx_shader_pass_blend,
982                 fxd->runtime.fx_sh, fxd->runtime.fx_sh);
983
984         /* blur shadow */
985         draw_gpencil_do_blur(
986                 e_data, vedata, &fxd->runtime,
987                 fxd->samples,
988                 fxd->blur[0], fxd->blur[1],
989                 &fxd->blur[0]);
990
991         /* resolve */
992         GPU_framebuffer_bind(fbl->temp_fb_b);
993         GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
994         DRW_draw_pass_subset(
995                 psl->fx_shader_pass_blend,
996                 fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
997
998         /* copy pass from b to a for ping-pong frame buffers */
999         e_data->input_depth_tx = e_data->temp_depth_tx_b;
1000         e_data->input_color_tx = e_data->temp_color_tx_b;
1001
1002         GPU_framebuffer_bind(fbl->temp_fb_a);
1003         GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
1004         DRW_draw_pass(psl->mix_pass_noblend);
1005 }
1006
1007 /* helper to draw GLOW passes */
1008 static void draw_gpencil_glow_passes(
1009         GPENCIL_e_data *e_data,
1010         GPENCIL_Data *vedata,
1011         GlowShaderFxData *fxd)
1012 {
1013         if (fxd->runtime.fx_sh_b == NULL) {
1014                 return;
1015         }
1016
1017         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
1018         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
1019
1020         const float clearcol[4] = {0.0f};
1021
1022         /* prepare glow */
1023         GPU_framebuffer_bind(fbl->temp_fb_fx);
1024         GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
1025         DRW_draw_pass_subset(
1026                 psl->fx_shader_pass_blend,
1027                 fxd->runtime.fx_sh, fxd->runtime.fx_sh);
1028
1029         /* blur glow */
1030         draw_gpencil_do_blur(
1031                 e_data, vedata, &fxd->runtime,
1032                 fxd->samples,
1033                 fxd->blur[0], fxd->blur[0],
1034                 &fxd->blur[0]);
1035
1036         /* resolve */
1037         GPU_framebuffer_bind(fbl->temp_fb_b);
1038         GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
1039
1040         /* reuses blur field to keep alpha mode */
1041         fxd->blur[1] = (fxd->flag & FX_GLOW_USE_ALPHA) ? 1 : 0;
1042
1043         DRW_draw_pass_subset(
1044                 psl->fx_shader_pass_blend,
1045                 fxd->runtime.fx_sh_c, fxd->runtime.fx_sh_c);
1046
1047         /* copy pass from b to a for ping-pong frame buffers */
1048         e_data->input_depth_tx = e_data->temp_depth_tx_b;
1049         e_data->input_color_tx = e_data->temp_color_tx_b;
1050
1051         GPU_framebuffer_bind(fbl->temp_fb_a);
1052         GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
1053         DRW_draw_pass(psl->mix_pass_noblend);
1054 }
1055
1056 /* apply all object fx effects */
1057 void DRW_gpencil_fx_draw(
1058         GPENCIL_e_data *e_data,
1059         GPENCIL_Data *vedata, tGPencilObjectCache *cache)
1060 {
1061         GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
1062         GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
1063         GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
1064
1065         /* loop FX modifiers */
1066         for (ShaderFxData *fx = cache->shader_fx.first; fx; fx = fx->next) {
1067                 if (effect_is_active(cache->gpd, fx, stl->storage->is_render)) {
1068                         switch (fx->type) {
1069
1070                                 case eShaderFxType_Blur:
1071                                 {
1072                                         BlurShaderFxData *fxd = (BlurShaderFxData *)fx;
1073                                         draw_gpencil_blur_passes(e_data, vedata, fxd);
1074                                         break;
1075                                 }
1076                                 case eShaderFxType_Colorize:
1077                                 {
1078                                         ColorizeShaderFxData *fxd = (ColorizeShaderFxData *)fx;
1079                                         gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
1080                                         break;
1081                                 }
1082                                 case eShaderFxType_Flip:
1083                                 {
1084                                         FlipShaderFxData *fxd = (FlipShaderFxData *)fx;
1085                                         gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
1086                                         break;
1087                                 }
1088                                 case eShaderFxType_Light:
1089                                 {
1090                                         LightShaderFxData *fxd = (LightShaderFxData *)fx;
1091                                         gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
1092                                         break;
1093                                 }
1094                                 case eShaderFxType_Pixel:
1095                                 {
1096                                         PixelShaderFxData *fxd = (PixelShaderFxData *)fx;
1097                                         gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
1098                                         break;
1099                                 }
1100                                 case eShaderFxType_Rim:
1101                                 {
1102                                         RimShaderFxData *fxd = (RimShaderFxData *)fx;
1103                                         draw_gpencil_rim_passes(e_data, vedata, fxd);
1104                                         break;
1105                                 }
1106                                 case eShaderFxType_Shadow:
1107                                 {
1108                                         ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
1109                                         draw_gpencil_shadow_passes(e_data, vedata, fxd);
1110                                         break;
1111                                 }
1112                                 case eShaderFxType_Glow:
1113                                 {
1114                                         GlowShaderFxData *fxd = (GlowShaderFxData *)fx;
1115                                         draw_gpencil_glow_passes(e_data, vedata, fxd);
1116                                         break;
1117                                 }
1118                                 case eShaderFxType_Swirl:
1119                                 {
1120                                         SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
1121                                         gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
1122                                         break;
1123                                 }
1124                                 case eShaderFxType_Wave:
1125                                 {
1126                                         WaveShaderFxData *fxd = (WaveShaderFxData *)fx;
1127                                         gpencil_draw_fx_pass(e_data, psl, fbl, fxd->runtime.fx_sh, false);
1128                                         break;
1129                                 }
1130                                 default:
1131                                         break;
1132                         }
1133                 }
1134         }
1135 }