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