Eevee: Fix world test for volumetric
[blender.git] / source / blender / draw / engines / eevee / eevee_effects.c
1 /*
2  * Copyright 2016, 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): Blender Institute
19  *
20  */
21
22 /* Gather all screen space effects technique such as Bloom, Motion Blur, DoF, SSAO, SSR, ...
23  */
24
25 /** \file eevee_effects.c
26  *  \ingroup draw_engine
27  */
28
29 #include "DRW_render.h"
30
31 #include "DNA_anim_types.h"
32 #include "DNA_camera_types.h"
33 #include "DNA_screen_types.h"
34 #include "DNA_view3d_types.h"
35 #include "DNA_world_types.h"
36
37 #include "BKE_camera.h"
38 #include "BKE_object.h"
39 #include "BKE_animsys.h"
40 #include "BKE_screen.h"
41
42 #include "BLI_dynstr.h"
43
44 #include "eevee_private.h"
45 #include "GPU_texture.h"
46
47 typedef struct EEVEE_LightProbeData {
48         short probe_id, shadow_id;
49 } EEVEE_LightProbeData;
50
51 static struct {
52         /* Downsample Depth */
53         struct GPUShader *minmaxz_downlevel_sh;
54         struct GPUShader *minmaxz_downdepth_sh;
55         struct GPUShader *minmaxz_copydepth_sh;
56
57         /* Motion Blur */
58         struct GPUShader *motion_blur_sh;
59
60         /* Bloom */
61         struct GPUShader *bloom_blit_sh[2];
62         struct GPUShader *bloom_downsample_sh[2];
63         struct GPUShader *bloom_upsample_sh[2];
64         struct GPUShader *bloom_resolve_sh[2];
65
66         /* Depth Of Field */
67         struct GPUShader *dof_downsample_sh;
68         struct GPUShader *dof_scatter_sh;
69         struct GPUShader *dof_resolve_sh;
70
71         /* Volumetric */
72         struct GPUShader *volumetric_upsample_sh;
73
74         struct GPUTexture *depth_src;
75 } e_data = {NULL}; /* Engine data */
76
77 extern char datatoc_effect_minmaxz_frag_glsl[];
78 extern char datatoc_effect_motion_blur_frag_glsl[];
79 extern char datatoc_effect_bloom_frag_glsl[];
80 extern char datatoc_effect_dof_vert_glsl[];
81 extern char datatoc_effect_dof_geom_glsl[];
82 extern char datatoc_effect_dof_frag_glsl[];
83 extern char datatoc_tonemap_frag_glsl[];
84 extern char datatoc_volumetric_frag_glsl[];
85
86 static void eevee_motion_blur_camera_get_matrix_at_time(
87         Scene *scene, ARegion *ar, RegionView3D *rv3d, View3D *v3d, Object *camera, float time, float r_mat[4][4])
88 {
89         float obmat[4][4];
90
91         /* HACK */
92         Object cam_cpy; Camera camdata_cpy;
93         memcpy(&cam_cpy, camera, sizeof(cam_cpy));
94         memcpy(&camdata_cpy, camera->data, sizeof(camdata_cpy));
95         cam_cpy.data = &camdata_cpy;
96
97         /* Past matrix */
98         /* FIXME : This is a temporal solution that does not take care of parent animations */
99         /* Recalc Anim manualy */
100         BKE_animsys_evaluate_animdata(scene, &cam_cpy.id, cam_cpy.adt, time, ADT_RECALC_ALL);
101         BKE_animsys_evaluate_animdata(scene, &camdata_cpy.id, camdata_cpy.adt, time, ADT_RECALC_ALL);
102         BKE_object_where_is_calc_time(scene, &cam_cpy, time);
103
104         /* Compute winmat */
105         CameraParams params;
106         BKE_camera_params_init(&params);
107
108         /* copy of BKE_camera_params_from_view3d */
109         {
110                 params.lens = v3d->lens;
111                 params.clipsta = v3d->near;
112                 params.clipend = v3d->far;
113
114                 /* camera view */
115                 BKE_camera_params_from_object(&params, &cam_cpy);
116
117                 params.zoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
118
119                 params.offsetx = 2.0f * rv3d->camdx * params.zoom;
120                 params.offsety = 2.0f * rv3d->camdy * params.zoom;
121
122                 params.shiftx *= params.zoom;
123                 params.shifty *= params.zoom;
124
125                 params.zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB / params.zoom;
126         }
127
128         BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, 1.0f, 1.0f);
129         BKE_camera_params_compute_matrix(&params);
130
131         /* FIXME Should be done per view (MULTIVIEW) */
132         normalize_m4_m4(obmat, cam_cpy.obmat);
133         invert_m4(obmat);
134         mul_m4_m4m4(r_mat, params.winmat, obmat);
135 }
136
137 void EEVEE_effects_init(EEVEE_Data *vedata)
138 {
139         EEVEE_StorageList *stl = vedata->stl;
140         EEVEE_FramebufferList *fbl = vedata->fbl;
141         EEVEE_TextureList *txl = vedata->txl;
142         EEVEE_EffectsInfo *effects;
143
144         const DRWContextState *draw_ctx = DRW_context_state_get();
145         SceneLayer *scene_layer = draw_ctx->sl;
146         Scene *scene = draw_ctx->scene;
147         View3D *v3d = draw_ctx->v3d;
148         RegionView3D *rv3d = draw_ctx->rv3d;
149         ARegion *ar = draw_ctx->ar;
150         IDProperty *props = BKE_scene_layer_engine_evaluated_get(scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
151
152         const float *viewport_size = DRW_viewport_size_get();
153
154         /* Shaders */
155         if (!e_data.motion_blur_sh) {
156                 e_data.volumetric_upsample_sh = DRW_shader_create_fullscreen(datatoc_volumetric_frag_glsl, "#define STEP_UPSAMPLE\n");
157
158                 e_data.minmaxz_downlevel_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, NULL);
159                 e_data.minmaxz_downdepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define INPUT_DEPTH\n");
160                 e_data.minmaxz_copydepth_sh = DRW_shader_create_fullscreen(datatoc_effect_minmaxz_frag_glsl, "#define INPUT_DEPTH\n"
161                                                                                                              "#define COPY_DEPTH\n");
162
163                 e_data.motion_blur_sh = DRW_shader_create_fullscreen(datatoc_effect_motion_blur_frag_glsl, NULL);
164
165                 e_data.dof_downsample_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
166                                                                 datatoc_effect_dof_frag_glsl, "#define STEP_DOWNSAMPLE\n");
167                 e_data.dof_scatter_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
168                                                              datatoc_effect_dof_frag_glsl, "#define STEP_SCATTER\n");
169                 e_data.dof_resolve_sh = DRW_shader_create(datatoc_effect_dof_vert_glsl, NULL,
170                                                              datatoc_effect_dof_frag_glsl, "#define STEP_RESOLVE\n");
171
172                 e_data.bloom_blit_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_BLIT\n");
173                 e_data.bloom_blit_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_BLIT\n"
174                                                                                                        "#define HIGH_QUALITY\n");
175
176                 e_data.bloom_downsample_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_DOWNSAMPLE\n");
177                 e_data.bloom_downsample_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_DOWNSAMPLE\n"
178                                                                                                              "#define HIGH_QUALITY\n");
179
180                 e_data.bloom_upsample_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_UPSAMPLE\n");
181                 e_data.bloom_upsample_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_UPSAMPLE\n"
182                                                                                                            "#define HIGH_QUALITY\n");
183
184                 e_data.bloom_resolve_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_RESOLVE\n");
185                 e_data.bloom_resolve_sh[1] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl, "#define STEP_RESOLVE\n"
186                                                                                                           "#define HIGH_QUALITY\n");
187         }
188
189         if (!stl->effects) {
190                 stl->effects = MEM_callocN(sizeof(EEVEE_EffectsInfo), "EEVEE_EffectsInfo");
191         }
192
193         effects = stl->effects;
194
195         int enabled_effects = 0;
196
197         if (BKE_collection_engine_property_value_get_bool(props, "motion_blur_enable")) {
198                 /* Update Motion Blur Matrices */
199                 if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
200                         float persmat[4][4];
201                         float ctime = BKE_scene_frame_get(scene);
202                         float delta = BKE_collection_engine_property_value_get_float(props, "motion_blur_shutter");
203
204                         /* Current matrix */
205                         eevee_motion_blur_camera_get_matrix_at_time(scene, ar, rv3d, v3d, v3d->camera, ctime, effects->current_ndc_to_world);
206
207                         /* Viewport Matrix */
208                         DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
209
210                         /* Only continue if camera is not being keyed */
211                         if (compare_m4m4(persmat, effects->current_ndc_to_world, 0.0001f)) {
212
213                                 /* Past matrix */
214                                 eevee_motion_blur_camera_get_matrix_at_time(scene, ar, rv3d, v3d, v3d->camera, ctime - delta, effects->past_world_to_ndc);
215
216 #if 0       /* for future high quality blur */
217                                 /* Future matrix */
218                                 eevee_motion_blur_camera_get_matrix_at_time(scene, ar, rv3d, v3d, v3d->camera, ctime + delta, effects->future_world_to_ndc);
219 #endif
220                                 invert_m4(effects->current_ndc_to_world);
221
222                                 effects->motion_blur_samples = BKE_collection_engine_property_value_get_int(props, "motion_blur_samples");
223                                 enabled_effects |= EFFECT_MOTION_BLUR;
224                         }
225                 }
226         }
227
228         if (BKE_collection_engine_property_value_get_bool(props, "bloom_enable")) {
229                 /* Bloom */
230                 int blitsize[2], texsize[2];
231
232                 /* Blit Buffer */
233                 effects->source_texel_size[0] = 1.0f / viewport_size[0];
234                 effects->source_texel_size[1] = 1.0f / viewport_size[1];
235
236                 blitsize[0] = (int)viewport_size[0];
237                 blitsize[1] = (int)viewport_size[1];
238
239                 effects->blit_texel_size[0] = 1.0f / (float)blitsize[0];
240                 effects->blit_texel_size[1] = 1.0f / (float)blitsize[1];
241
242                 DRWFboTexture tex_blit = {&txl->bloom_blit, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
243                 DRW_framebuffer_init(&fbl->bloom_blit_fb, &draw_engine_eevee_type,
244                                     (int)blitsize[0], (int)blitsize[1],
245                                     &tex_blit, 1);
246
247                 /* Parameters */
248                 float threshold = BKE_collection_engine_property_value_get_float(props, "bloom_threshold");
249                 float knee = BKE_collection_engine_property_value_get_float(props, "bloom_knee");
250                 float intensity = BKE_collection_engine_property_value_get_float(props, "bloom_intensity");
251                 float radius = BKE_collection_engine_property_value_get_float(props, "bloom_radius");
252
253                 /* determine the iteration count */
254                 const float minDim = (float)MIN2(blitsize[0], blitsize[1]);
255                 const float maxIter = (radius - 8.0f) + log(minDim) / log(2);
256                 const int maxIterInt = effects->bloom_iteration_ct = (int)maxIter;
257
258                 CLAMP(effects->bloom_iteration_ct, 1, MAX_BLOOM_STEP);
259
260                 effects->bloom_sample_scale = 0.5f + maxIter - (float)maxIterInt;
261                 effects->bloom_curve_threshold[0] = threshold - knee;
262                 effects->bloom_curve_threshold[1] = knee * 2.0f;
263                 effects->bloom_curve_threshold[2] = 0.25f / max_ff(1e-5f, knee);
264                 effects->bloom_curve_threshold[3] = threshold;
265                 effects->bloom_intensity = intensity;
266
267                 /* Downsample buffers */
268                 copy_v2_v2_int(texsize, blitsize);
269                 for (int i = 0; i < effects->bloom_iteration_ct; ++i) {
270                         texsize[0] /= 2; texsize[1] /= 2;
271                         texsize[0] = MAX2(texsize[0], 2);
272                         texsize[1] = MAX2(texsize[1], 2);
273
274                         effects->downsamp_texel_size[i][0] = 1.0f / (float)texsize[0];
275                         effects->downsamp_texel_size[i][1] = 1.0f / (float)texsize[1];
276
277                         DRWFboTexture tex_bloom = {&txl->bloom_downsample[i], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
278                         DRW_framebuffer_init(&fbl->bloom_down_fb[i], &draw_engine_eevee_type,
279                                             (int)texsize[0], (int)texsize[1],
280                                             &tex_bloom, 1);
281                 }
282
283                 /* Upsample buffers */
284                 copy_v2_v2_int(texsize, blitsize);
285                 for (int i = 0; i < effects->bloom_iteration_ct - 1; ++i) {
286                         texsize[0] /= 2; texsize[1] /= 2;
287                         texsize[0] = MAX2(texsize[0], 2);
288                         texsize[1] = MAX2(texsize[1], 2);
289
290                         DRWFboTexture tex_bloom = {&txl->bloom_upsample[i], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
291                         DRW_framebuffer_init(&fbl->bloom_accum_fb[i], &draw_engine_eevee_type,
292                                             (int)texsize[0], (int)texsize[1],
293                                             &tex_bloom, 1);
294                 }
295
296                 enabled_effects |= EFFECT_BLOOM;
297         }
298
299         if (BKE_collection_engine_property_value_get_bool(props, "dof_enable")) {
300                 /* Depth Of Field */
301                 if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
302                         Camera *cam = (Camera *)v3d->camera->data;
303
304                         /* Retreive Near and Far distance */
305                         effects->dof_near_far[0] = -cam->clipsta;
306                         effects->dof_near_far[1] = -cam->clipend;
307
308                         int buffer_size[2] = {(int)viewport_size[0] / 2, (int)viewport_size[1] / 2};
309
310                         struct GPUTexture **dof_down_near = &txl->dof_down_near;
311                         bool fb_reset = false;
312
313                         /* Reuse buffer from Bloom if available */
314                         /* WATCH IT : must have the same size */
315                         if ((enabled_effects & EFFECT_BLOOM) != 0) {
316                                 dof_down_near = &txl->bloom_downsample[0]; /* should always exists */
317                                 if ((effects->enabled_effects & EFFECT_BLOOM) == 0) {
318                                         fb_reset = true;
319                                 }
320                         }
321                         else if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
322                                 fb_reset = true;
323                         }
324
325                         /* if framebuffer config must be changed */
326                         if (fb_reset && (fbl->dof_down_fb != NULL)) {
327                                 DRW_framebuffer_free(fbl->dof_down_fb);
328                                 fbl->dof_down_fb = NULL;
329                         }
330
331                         /* Setup buffers */
332                         DRWFboTexture tex_down[3] = {{dof_down_near, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}, /* filter to not interfeer with bloom */
333                                                      {&txl->dof_down_far, DRW_TEX_RGB_11_11_10, 0},
334                                                      {&txl->dof_coc, DRW_TEX_RG_16, 0}};
335                         DRW_framebuffer_init(&fbl->dof_down_fb, &draw_engine_eevee_type, buffer_size[0], buffer_size[1], tex_down, 3);
336
337                         DRWFboTexture tex_scatter_far = {&txl->dof_far_blur, DRW_TEX_RGBA_16, DRW_TEX_FILTER};
338                         DRW_framebuffer_init(&fbl->dof_scatter_far_fb, &draw_engine_eevee_type, buffer_size[0], buffer_size[1], &tex_scatter_far, 1);
339
340                         DRWFboTexture tex_scatter_near = {&txl->dof_near_blur, DRW_TEX_RGBA_16, DRW_TEX_FILTER};
341                         DRW_framebuffer_init(&fbl->dof_scatter_near_fb, &draw_engine_eevee_type, buffer_size[0], buffer_size[1], &tex_scatter_near, 1);
342
343                         /* Parameters */
344                         /* TODO UI Options */
345                         float fstop = cam->gpu_dof.fstop;
346                         float blades = cam->gpu_dof.num_blades;
347                         float rotation = cam->gpu_dof.rotation;
348                         float ratio = 1.0f / cam->gpu_dof.ratio;
349                         float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
350                         float focus_dist = BKE_camera_object_dof_distance(v3d->camera);
351                         float focal_len = cam->lens;
352
353                         UNUSED_VARS(rotation, ratio);
354
355                         /* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
356                          * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though
357                          * because the shader reads coordinates in world space, which is in blender units.
358                          * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */
359                         float scale = (scene->unit.system) ? scene->unit.scale_length : 1.0f;
360                         float scale_camera = 0.001f / scale;
361                         /* we want radius here for the aperture number  */
362                         float aperture = 0.5f * scale_camera * focal_len / fstop;
363                         float focal_len_scaled = scale_camera * focal_len;
364                         float sensor_scaled = scale_camera * sensor;
365
366                         effects->dof_params[0] = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
367                         effects->dof_params[1] = -focus_dist;
368                         effects->dof_params[2] = viewport_size[0] / (rv3d->viewcamtexcofac[0] * sensor_scaled);
369                         effects->dof_bokeh[0] = blades;
370                         effects->dof_bokeh[1] = rotation;
371                         effects->dof_bokeh[2] = ratio;
372                         effects->dof_bokeh[3] = BKE_collection_engine_property_value_get_float(props, "bokeh_max_size");
373
374                         enabled_effects |= EFFECT_DOF;
375                 }
376         }
377
378         effects->enabled_effects = enabled_effects;
379
380         /* Only allocate if at least one effect is activated */
381         if (effects->enabled_effects != 0) {
382                 /* Ping Pong buffer */
383                 DRWFboTexture tex = {&txl->color_post, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER};
384
385                 DRW_framebuffer_init(&fbl->effect_fb, &draw_engine_eevee_type,
386                                     (int)viewport_size[0], (int)viewport_size[1],
387                                     &tex, 1);
388         }
389
390         {
391                 /* Ambient Occlusion*/
392                 stl->effects->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance");
393                 stl->effects->ao_samples = BKE_collection_engine_property_value_get_int(props, "gtao_samples");
394                 stl->effects->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor");
395         }
396
397         /* MinMax Pyramid */
398         /* TODO reduce precision */
399         DRWFboTexture tex = {&stl->g_data->minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP};
400
401         DRW_framebuffer_init(&fbl->minmaxz_fb, &draw_engine_eevee_type,
402                             (int)viewport_size[0] / 2, (int)viewport_size[1] / 2,
403                             &tex, 1);
404
405         if (BKE_collection_engine_property_value_get_bool(props, "volumetric_enable")) {
406                 /* Integration result */
407                 DRWFboTexture tex_vol = {&stl->g_data->volumetric, DRW_TEX_RGBA_16, DRW_TEX_MIPMAP | DRW_TEX_FILTER | DRW_TEX_TEMP};
408
409                 DRW_framebuffer_init(&fbl->volumetric_fb, &draw_engine_eevee_type,
410                                     (int)viewport_size[0] / 2, (int)viewport_size[1] / 2,
411                                     &tex_vol, 1);
412
413                 World *wo = scene->world;
414                 if ((wo != NULL) && (wo->use_nodes) && (wo->nodetree != NULL)) {
415                         effects->enabled_effects |= EFFECT_VOLUMETRIC;
416                 }
417         }
418 }
419
420 static DRWShadingGroup *eevee_create_bloom_pass(const char *name, EEVEE_EffectsInfo *effects, struct GPUShader *sh, DRWPass **pass, bool upsample)
421 {
422         struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
423
424         *pass = DRW_pass_create(name, DRW_STATE_WRITE_COLOR);
425
426         DRWShadingGroup *grp = DRW_shgroup_create(sh, *pass);
427         DRW_shgroup_call_add(grp, quad, NULL);
428         DRW_shgroup_uniform_buffer(grp, "sourceBuffer", &effects->unf_source_buffer);
429         DRW_shgroup_uniform_vec2(grp, "sourceBufferTexelSize", effects->unf_source_texel_size, 1);
430         if (upsample) {
431                 DRW_shgroup_uniform_buffer(grp, "baseBuffer", &effects->unf_base_buffer);
432                 DRW_shgroup_uniform_float(grp, "sampleScale", &effects->bloom_sample_scale, 1);
433         }
434
435         return grp;
436 }
437
438 void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
439 {
440         EEVEE_PassList *psl = vedata->psl;
441         EEVEE_StorageList *stl = vedata->stl;
442         EEVEE_TextureList *txl = vedata->txl;
443         EEVEE_EffectsInfo *effects = stl->effects;
444         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
445
446         struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
447
448         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
449                 const DRWContextState *draw_ctx = DRW_context_state_get();
450                 Scene *scene = draw_ctx->scene;
451                 struct World *wo = scene->world; /* Already checked non NULL */
452
453                 struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
454                 psl->volumetric_integrate_ps = DRW_pass_create("Volumetric Integration", DRW_STATE_WRITE_COLOR);
455                 DRWShadingGroup *grp = DRW_shgroup_material_create(mat, psl->volumetric_integrate_ps);
456
457                 if (grp != NULL) {
458                         DRW_shgroup_uniform_buffer(grp, "depthFull", &e_data.depth_src);
459                         DRW_shgroup_uniform_buffer(grp, "shadowCubes", &sldata->shadow_depth_cube_pool);
460                         DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
461                         DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
462                         DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
463                         DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
464                         DRW_shgroup_uniform_int(grp, "light_count", &sldata->lamps->num_light, 1);
465                         DRW_shgroup_uniform_int(grp, "grid_count", &sldata->probes->num_render_grid, 1);
466                         DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
467                         DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
468                         DRW_shgroup_call_add(grp, quad, NULL);
469
470                         psl->volumetric_resolve_ps = DRW_pass_create("Volumetric Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_TRANSMISSION);
471                         grp = DRW_shgroup_create(e_data.volumetric_upsample_sh, psl->volumetric_resolve_ps);
472                         DRW_shgroup_uniform_buffer(grp, "depthFull", &e_data.depth_src);
473                         DRW_shgroup_uniform_buffer(grp, "volumetricBuffer", &stl->g_data->volumetric);
474                         DRW_shgroup_call_add(grp, quad, NULL);
475                 }
476                 else {
477                         /* Compilation failled */
478                         effects->enabled_effects &= ~EFFECT_VOLUMETRIC;
479                 }
480         }
481
482         {
483                 psl->minmaxz_downlevel = DRW_pass_create("HiZ Down Level", DRW_STATE_WRITE_COLOR);
484                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.minmaxz_downlevel_sh, psl->minmaxz_downlevel);
485                 DRW_shgroup_uniform_buffer(grp, "depthBuffer", &stl->g_data->minmaxz);
486                 DRW_shgroup_call_add(grp, quad, NULL);
487
488                 psl->minmaxz_downdepth = DRW_pass_create("HiZ Down Depth", DRW_STATE_WRITE_COLOR);
489                 grp = DRW_shgroup_create(e_data.minmaxz_downdepth_sh, psl->minmaxz_downdepth);
490                 DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
491                 DRW_shgroup_call_add(grp, quad, NULL);
492
493                 psl->minmaxz_copydepth = DRW_pass_create("HiZ Copy Depth", DRW_STATE_WRITE_COLOR);
494                 grp = DRW_shgroup_create(e_data.minmaxz_copydepth_sh, psl->minmaxz_copydepth);
495                 DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
496                 DRW_shgroup_call_add(grp, quad, NULL);
497         }
498
499         {
500                 psl->motion_blur = DRW_pass_create("Motion Blur", DRW_STATE_WRITE_COLOR);
501
502                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.motion_blur_sh, psl->motion_blur);
503                 DRW_shgroup_uniform_int(grp, "samples", &effects->motion_blur_samples, 1);
504                 DRW_shgroup_uniform_mat4(grp, "currInvViewProjMatrix", (float *)effects->current_ndc_to_world);
505                 DRW_shgroup_uniform_mat4(grp, "pastViewProjMatrix", (float *)effects->past_world_to_ndc);
506                 DRW_shgroup_uniform_buffer(grp, "colorBuffer", &effects->source_buffer);
507                 DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
508                 DRW_shgroup_call_add(grp, quad, NULL);
509         }
510
511         {
512                 /**  Bloom algorithm
513                  *
514                  * Overview :
515                  * - Downsample the color buffer doing a small blur during each step.
516                  * - Accumulate bloom color using previously downsampled color buffers
517                  *   and do an upsample blur for each new accumulated layer.
518                  * - Finally add accumulation buffer onto the source color buffer.
519                  *
520                  *  [1/1] is original copy resolution (can be half or quater res for performance)
521                  *
522                  *                                [DOWNSAMPLE CHAIN]                      [UPSAMPLE CHAIN]
523                  *
524                  *  Source Color ── [Blit] ──>  Bright Color Extract [1/1]                  Final Color
525                  *                                        |                                      Λ
526                  *                                [Downsample First]       Source Color ─> + [Resolve]
527                  *                                        v                                      |
528                  *                              Color Downsampled [1/2] ────────────> + Accumulation Buffer [1/2]
529                  *                                        |                                      Λ
530                  *                                       ───                                    ───
531                  *                                      Repeat                                 Repeat
532                  *                                       ───                                    ───
533                  *                                        v                                      |
534                  *                              Color Downsampled [1/N-1] ──────────> + Accumulation Buffer [1/N-1]
535                  *                                        |                                      Λ
536                  *                                   [Downsample]                            [Upsample]
537                  *                                        v                                      |
538                  *                              Color Downsampled [1/N] ─────────────────────────┘
539                  **/
540                 DRWShadingGroup *grp;
541                 const bool use_highres = true;
542                 const bool use_antiflicker = true;
543                 eevee_create_bloom_pass("Bloom Downsample First", effects, e_data.bloom_downsample_sh[use_antiflicker], &psl->bloom_downsample_first, false);
544                 eevee_create_bloom_pass("Bloom Downsample", effects, e_data.bloom_downsample_sh[0], &psl->bloom_downsample, false);
545                 eevee_create_bloom_pass("Bloom Upsample", effects, e_data.bloom_upsample_sh[use_highres], &psl->bloom_upsample, true);
546                 grp = eevee_create_bloom_pass("Bloom Blit", effects, e_data.bloom_blit_sh[use_antiflicker], &psl->bloom_blit, false);
547                 DRW_shgroup_uniform_vec4(grp, "curveThreshold", effects->bloom_curve_threshold, 1);
548                 grp = eevee_create_bloom_pass("Bloom Resolve", effects, e_data.bloom_resolve_sh[use_highres], &psl->bloom_resolve, true);
549                 DRW_shgroup_uniform_float(grp, "bloomIntensity", &effects->bloom_intensity, 1);
550         }
551
552         {
553                 /**  Depth of Field algorithm
554                  *
555                  * Overview :
556                  * - Downsample the color buffer into 2 buffers weighted with
557                  *   CoC values. Also output CoC into a texture.
558                  * - Shoot quads for every pixel and expand it depending on the CoC.
559                  *   Do one pass for near Dof and one pass for far Dof.
560                  * - Finally composite the 2 blurred buffers with the original render.
561                  **/
562                 DRWShadingGroup *grp;
563
564                 psl->dof_down = DRW_pass_create("DoF Downsample", DRW_STATE_WRITE_COLOR);
565
566                 grp = DRW_shgroup_create(e_data.dof_downsample_sh, psl->dof_down);
567                 DRW_shgroup_uniform_buffer(grp, "colorBuffer", &effects->source_buffer);
568                 DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
569                 DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
570                 DRW_shgroup_uniform_vec3(grp, "dofParams", effects->dof_params, 1);
571                 DRW_shgroup_call_add(grp, quad, NULL);
572
573                 psl->dof_scatter = DRW_pass_create("DoF Scatter", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
574
575                 /* This create an empty batch of N triangles to be positioned
576                  * by the vertex shader 0.4ms against 6ms with instancing */
577                 const float *viewport_size = DRW_viewport_size_get();
578                 const int sprite_ct = ((int)viewport_size[0]/2) * ((int)viewport_size[1]/2); /* brackets matters */
579                 grp = DRW_shgroup_empty_tri_batch_create(e_data.dof_scatter_sh, psl->dof_scatter, sprite_ct);
580
581                 DRW_shgroup_uniform_buffer(grp, "colorBuffer", &effects->unf_source_buffer);
582                 DRW_shgroup_uniform_buffer(grp, "cocBuffer", &txl->dof_coc);
583                 DRW_shgroup_uniform_vec2(grp, "layerSelection", effects->dof_layer_select, 1);
584                 DRW_shgroup_uniform_vec4(grp, "bokehParams", effects->dof_bokeh, 1);
585
586                 psl->dof_resolve = DRW_pass_create("DoF Resolve", DRW_STATE_WRITE_COLOR);
587
588                 grp = DRW_shgroup_create(e_data.dof_resolve_sh, psl->dof_resolve);
589                 DRW_shgroup_uniform_buffer(grp, "colorBuffer", &effects->source_buffer);
590                 DRW_shgroup_uniform_buffer(grp, "nearBuffer", &txl->dof_near_blur);
591                 DRW_shgroup_uniform_buffer(grp, "farBuffer", &txl->dof_far_blur);
592                 DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
593                 DRW_shgroup_uniform_vec2(grp, "nearFar", effects->dof_near_far, 1);
594                 DRW_shgroup_uniform_vec3(grp, "dofParams", effects->dof_params, 1);
595                 DRW_shgroup_call_add(grp, quad, NULL);
596         }
597 }
598
599 #define SWAP_BUFFERS() {                           \
600         if (effects->source_buffer == txl->color) {    \
601                 effects->source_buffer = txl->color_post;  \
602                 effects->target_buffer = fbl->main;        \
603         }                                              \
604         else {                                         \
605                 effects->source_buffer = txl->color;       \
606                 effects->target_buffer = fbl->effect_fb;   \
607         }                                              \
608 } ((void)0)
609
610 static void minmax_downsample_cb(void *vedata, int UNUSED(level))
611 {
612         EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
613         DRW_draw_pass(psl->minmaxz_downlevel);
614 }
615
616 void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src)
617 {
618         EEVEE_PassList *psl = vedata->psl;
619         EEVEE_FramebufferList *fbl = vedata->fbl;
620         EEVEE_StorageList *stl = vedata->stl;
621
622         e_data.depth_src = depth_src;
623
624         /* Copy depth buffer to minmax texture top level */
625         DRW_framebuffer_texture_attach(fbl->minmaxz_fb, stl->g_data->minmaxz, 0, 0);
626         DRW_framebuffer_bind(fbl->minmaxz_fb);
627         DRW_draw_pass(psl->minmaxz_downdepth);
628         DRW_framebuffer_texture_detach(stl->g_data->minmaxz);
629
630         /* Create lower levels */
631         DRW_framebuffer_recursive_downsample(fbl->minmaxz_fb, stl->g_data->minmaxz, 6, &minmax_downsample_cb, vedata);
632 }
633
634 void EEVEE_effects_do_volumetrics(EEVEE_Data *vedata)
635 {
636         EEVEE_PassList *psl = vedata->psl;
637         EEVEE_FramebufferList *fbl = vedata->fbl;
638         EEVEE_StorageList *stl = vedata->stl;
639         EEVEE_EffectsInfo *effects = stl->effects;
640
641         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
642                 DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
643
644                 e_data.depth_src = dtxl->depth;
645
646                 /* Compute volumetric integration at halfres. */
647                 DRW_framebuffer_texture_attach(fbl->volumetric_fb, stl->g_data->volumetric, 0, 0);
648                 DRW_framebuffer_bind(fbl->volumetric_fb);
649                 DRW_draw_pass(psl->volumetric_integrate_ps);
650
651                 /* Resolve at fullres */
652                 DRW_framebuffer_texture_detach(dtxl->depth);
653                 DRW_framebuffer_bind(fbl->main);
654                 DRW_draw_pass(psl->volumetric_resolve_ps);
655
656                 /* Restore */
657                 DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
658         }
659 }
660
661 void EEVEE_draw_effects(EEVEE_Data *vedata)
662 {
663         EEVEE_PassList *psl = vedata->psl;
664         EEVEE_TextureList *txl = vedata->txl;
665         EEVEE_FramebufferList *fbl = vedata->fbl;
666         EEVEE_StorageList *stl = vedata->stl;
667         EEVEE_EffectsInfo *effects = stl->effects;
668
669         /* Default framebuffer and texture */
670         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
671         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
672
673         /* Init pointers */
674         effects->source_buffer = txl->color; /* latest updated texture */
675         effects->target_buffer = fbl->effect_fb; /* next target to render to */
676
677         /* Detach depth for effects to use it */
678         DRW_framebuffer_texture_detach(dtxl->depth);
679
680         /* Motion Blur */
681         if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) {
682                 DRW_framebuffer_bind(effects->target_buffer);
683                 DRW_draw_pass(psl->motion_blur);
684                 SWAP_BUFFERS();
685         }
686
687         /* Depth Of Field */
688         if ((effects->enabled_effects & EFFECT_DOF) != 0) {
689                 float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
690
691                 /* Downsample */
692                 DRW_framebuffer_bind(fbl->dof_down_fb);
693                 DRW_draw_pass(psl->dof_down);
694
695                 /* Scatter Far */
696                 effects->unf_source_buffer = txl->dof_down_far;
697                 copy_v2_fl2(effects->dof_layer_select, 0.0f, 1.0f);
698                 DRW_framebuffer_bind(fbl->dof_scatter_far_fb);
699                 DRW_framebuffer_clear(true, false, false, clear_col, 0.0f);
700                 DRW_draw_pass(psl->dof_scatter);
701
702                 /* Scatter Near */
703                 if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
704                         /* Reuse bloom half res buffer */
705                         effects->unf_source_buffer = txl->bloom_downsample[0];
706                 }
707                 else {
708                         effects->unf_source_buffer = txl->dof_down_near;
709                 }
710                 copy_v2_fl2(effects->dof_layer_select, 1.0f, 0.0f);
711                 DRW_framebuffer_bind(fbl->dof_scatter_near_fb);
712                 DRW_framebuffer_clear(true, false, false, clear_col, 0.0f);
713                 DRW_draw_pass(psl->dof_scatter);
714
715                 /* Resolve */
716                 DRW_framebuffer_bind(effects->target_buffer);
717                 DRW_draw_pass(psl->dof_resolve);
718                 SWAP_BUFFERS();
719         }
720
721         /* Bloom */
722         if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
723                 struct GPUTexture *last;
724
725                 /* Extract bright pixels */
726                 copy_v2_v2(effects->unf_source_texel_size, effects->source_texel_size);
727                 effects->unf_source_buffer = effects->source_buffer;
728
729                 DRW_framebuffer_bind(fbl->bloom_blit_fb);
730                 DRW_draw_pass(psl->bloom_blit);
731
732                 /* Downsample */
733                 copy_v2_v2(effects->unf_source_texel_size, effects->blit_texel_size);
734                 effects->unf_source_buffer = txl->bloom_blit;
735
736                 DRW_framebuffer_bind(fbl->bloom_down_fb[0]);
737                 DRW_draw_pass(psl->bloom_downsample_first);
738
739                 last = txl->bloom_downsample[0];
740
741                 for (int i = 1; i < effects->bloom_iteration_ct; ++i) {
742                         copy_v2_v2(effects->unf_source_texel_size, effects->downsamp_texel_size[i-1]);
743                         effects->unf_source_buffer = last;
744
745                         DRW_framebuffer_bind(fbl->bloom_down_fb[i]);
746                         DRW_draw_pass(psl->bloom_downsample);
747
748                         /* Used in next loop */
749                         last = txl->bloom_downsample[i];
750                 }
751
752                 /* Upsample and accumulate */
753                 for (int i = effects->bloom_iteration_ct - 2; i >= 0; --i) {
754                         copy_v2_v2(effects->unf_source_texel_size, effects->downsamp_texel_size[i]);
755                         effects->unf_source_buffer = txl->bloom_downsample[i];
756                         effects->unf_base_buffer = last;
757
758                         DRW_framebuffer_bind(fbl->bloom_accum_fb[i]);
759                         DRW_draw_pass(psl->bloom_upsample);
760
761                         last = txl->bloom_upsample[i];
762                 }
763
764                 /* Resolve */
765                 copy_v2_v2(effects->unf_source_texel_size, effects->downsamp_texel_size[0]);
766                 effects->unf_source_buffer = last;
767                 effects->unf_base_buffer = effects->source_buffer;
768
769                 DRW_framebuffer_bind(effects->target_buffer);
770                 DRW_draw_pass(psl->bloom_resolve);
771                 SWAP_BUFFERS();
772         }
773
774         /* Restore default framebuffer */
775         DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
776         DRW_framebuffer_bind(dfbl->default_fb);
777
778         /* Tonemapping */
779         DRW_transform_to_display(effects->source_buffer);
780 }
781
782 void EEVEE_effects_free(void)
783 {
784         DRW_SHADER_FREE_SAFE(e_data.volumetric_upsample_sh);
785
786         DRW_SHADER_FREE_SAFE(e_data.minmaxz_downlevel_sh);
787         DRW_SHADER_FREE_SAFE(e_data.minmaxz_downdepth_sh);
788         DRW_SHADER_FREE_SAFE(e_data.minmaxz_copydepth_sh);
789
790         DRW_SHADER_FREE_SAFE(e_data.motion_blur_sh);
791         DRW_SHADER_FREE_SAFE(e_data.dof_downsample_sh);
792         DRW_SHADER_FREE_SAFE(e_data.dof_scatter_sh);
793         DRW_SHADER_FREE_SAFE(e_data.dof_resolve_sh);
794
795         DRW_SHADER_FREE_SAFE(e_data.bloom_blit_sh[0]);
796         DRW_SHADER_FREE_SAFE(e_data.bloom_downsample_sh[0]);
797         DRW_SHADER_FREE_SAFE(e_data.bloom_upsample_sh[0]);
798         DRW_SHADER_FREE_SAFE(e_data.bloom_resolve_sh[0]);
799         DRW_SHADER_FREE_SAFE(e_data.bloom_blit_sh[1]);
800         DRW_SHADER_FREE_SAFE(e_data.bloom_downsample_sh[1]);
801         DRW_SHADER_FREE_SAFE(e_data.bloom_upsample_sh[1]);
802         DRW_SHADER_FREE_SAFE(e_data.bloom_resolve_sh[1]);
803 }