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