Workbench: Fix crash when using more than one metaball
[blender.git] / source / blender / draw / engines / workbench / workbench_deferred.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 /** \file workbench_deferred.c
23  *  \ingroup draw_engine
24  */
25
26 #include "workbench_private.h"
27
28 #include "BIF_gl.h"
29
30 #include "BLI_alloca.h"
31 #include "BLI_dynstr.h"
32 #include "BLI_utildefines.h"
33 #include "BLI_rand.h"
34 #include "BLI_string_utils.h"
35
36 #include "BKE_node.h"
37 #include "BKE_modifier.h"
38 #include "BKE_object.h"
39 #include "BKE_particle.h"
40
41 #include "DNA_image_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_node_types.h"
45
46 #include "ED_uvedit.h"
47
48 #include "GPU_shader.h"
49 #include "GPU_texture.h"
50 #include "GPU_extensions.h"
51
52 #include "../eevee/eevee_lut.h" /* TODO find somewhere to share blue noise Table */
53
54 /* *********** STATIC *********** */
55
56 /* #define DEBUG_SHADOW_VOLUME */
57
58 #ifdef DEBUG_SHADOW_VOLUME
59 #  include "draw_debug.h"
60 #endif
61
62 static struct {
63         struct GPUShader *prepass_sh_cache[MAX_PREPASS_SHADERS];
64         struct GPUShader *composite_sh_cache[MAX_COMPOSITE_SHADERS];
65         struct GPUShader *cavity_sh[MAX_CAVITY_SHADERS];
66         struct GPUShader *background_sh[2];
67         struct GPUShader *ghost_resolve_sh;
68         struct GPUShader *shadow_fail_sh;
69         struct GPUShader *shadow_fail_manifold_sh;
70         struct GPUShader *shadow_pass_sh;
71         struct GPUShader *shadow_pass_manifold_sh;
72         struct GPUShader *shadow_caps_sh;
73         struct GPUShader *shadow_caps_manifold_sh;
74
75         struct GPUTexture *ghost_depth_tx; /* ref only, not alloced */
76         struct GPUTexture *object_id_tx; /* ref only, not alloced */
77         struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
78         struct GPUTexture *cavity_buffer_tx; /* ref only, not alloced */
79         struct GPUTexture *metallic_buffer_tx; /* ref only, not alloced */
80         struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */
81         struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
82
83         SceneDisplay display; /* world light direction for shadows */
84         int next_object_id;
85
86         struct GPUUniformBuffer *sampling_ubo;
87         struct GPUTexture *jitter_tx;
88         int cached_sample_num;
89 } e_data = {{NULL}};
90
91 /* Shaders */
92 extern char datatoc_common_hair_lib_glsl[];
93
94 extern char datatoc_workbench_prepass_vert_glsl[];
95 extern char datatoc_workbench_prepass_frag_glsl[];
96 extern char datatoc_workbench_cavity_frag_glsl[];
97 extern char datatoc_workbench_deferred_composite_frag_glsl[];
98 extern char datatoc_workbench_deferred_background_frag_glsl[];
99 extern char datatoc_workbench_ghost_resolve_frag_glsl[];
100
101 extern char datatoc_workbench_shadow_vert_glsl[];
102 extern char datatoc_workbench_shadow_geom_glsl[];
103 extern char datatoc_workbench_shadow_caps_geom_glsl[];
104 extern char datatoc_workbench_shadow_debug_frag_glsl[];
105
106 extern char datatoc_workbench_background_lib_glsl[];
107 extern char datatoc_workbench_cavity_lib_glsl[];
108 extern char datatoc_workbench_common_lib_glsl[];
109 extern char datatoc_workbench_data_lib_glsl[];
110 extern char datatoc_workbench_object_outline_lib_glsl[];
111 extern char datatoc_workbench_curvature_lib_glsl[];
112 extern char datatoc_workbench_world_light_lib_glsl[];
113
114 extern char datatoc_gpu_shader_depth_only_frag_glsl[];
115
116 static char *workbench_build_composite_frag(WORKBENCH_PrivateData *wpd)
117 {
118         char *str = NULL;
119
120         DynStr *ds = BLI_dynstr_new();
121
122         BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
123         BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
124         BLI_dynstr_append(ds, datatoc_workbench_background_lib_glsl);
125
126         if (!FLAT_ENABLED(wpd)) {
127                 BLI_dynstr_append(ds, datatoc_workbench_world_light_lib_glsl);
128         }
129         if (OBJECT_OUTLINE_ENABLED(wpd)) {
130                 BLI_dynstr_append(ds, datatoc_workbench_object_outline_lib_glsl);
131         }
132         if (CURVATURE_ENABLED(wpd)) {
133                 BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
134         }
135
136         BLI_dynstr_append(ds, datatoc_workbench_deferred_composite_frag_glsl);
137
138         str = BLI_dynstr_get_cstring(ds);
139         BLI_dynstr_free(ds);
140         return str;
141 }
142
143 static char *workbench_build_prepass_frag(void)
144 {
145         char *str = NULL;
146
147         DynStr *ds = BLI_dynstr_new();
148
149         BLI_dynstr_append(ds, datatoc_workbench_data_lib_glsl);
150         BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
151         BLI_dynstr_append(ds, datatoc_workbench_prepass_frag_glsl);
152
153         str = BLI_dynstr_get_cstring(ds);
154         BLI_dynstr_free(ds);
155         return str;
156 }
157
158 static char *workbench_build_prepass_vert(bool is_hair)
159 {
160         char *str = NULL;
161         if (!is_hair) {
162                 return BLI_strdup(datatoc_workbench_prepass_vert_glsl);
163         }
164
165         DynStr *ds = BLI_dynstr_new();
166
167         BLI_dynstr_append(ds, datatoc_common_hair_lib_glsl);
168         BLI_dynstr_append(ds, datatoc_workbench_prepass_vert_glsl);
169
170         str = BLI_dynstr_get_cstring(ds);
171         BLI_dynstr_free(ds);
172         return str;
173 }
174
175 static char *workbench_build_cavity_frag(bool cavity, bool curvature, bool high_dpi)
176 {
177         char *str = NULL;
178
179         DynStr *ds = BLI_dynstr_new();
180
181         if (cavity) {
182                 BLI_dynstr_append(ds, "#define USE_CAVITY\n");
183         }
184         if (curvature) {
185                 BLI_dynstr_append(ds, "#define USE_CURVATURE\n");
186         }
187         if (high_dpi) {
188                 BLI_dynstr_append(ds, "#define CURVATURE_OFFSET 2\n");
189         }
190         if (NORMAL_ENCODING_ENABLED()) {
191                 BLI_dynstr_append(ds, "#define WORKBENCH_ENCODE_NORMALS\n");
192         }
193         BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
194         BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
195         BLI_dynstr_append(ds, datatoc_workbench_cavity_frag_glsl);
196         BLI_dynstr_append(ds, datatoc_workbench_cavity_lib_glsl);
197
198         str = BLI_dynstr_get_cstring(ds);
199         BLI_dynstr_free(ds);
200         return str;
201 }
202
203 static GPUShader *workbench_cavity_shader_get(bool cavity, bool curvature)
204 {
205         const bool high_dpi = (U.pixelsize > 1.5f);
206         int index = 0;
207         SET_FLAG_FROM_TEST(index, cavity, 1 << 0);
208         SET_FLAG_FROM_TEST(index, curvature, 1 << 1);
209         SET_FLAG_FROM_TEST(index, high_dpi, 1 << 2);
210
211         GPUShader **sh = &e_data.cavity_sh[index];
212         if (*sh == NULL) {
213                 char *cavity_frag = workbench_build_cavity_frag(cavity, curvature, high_dpi);
214                 *sh = DRW_shader_create_fullscreen(cavity_frag, NULL);
215                 MEM_freeN(cavity_frag);
216         }
217         return *sh;
218 }
219
220 static GPUShader *ensure_deferred_prepass_shader(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair)
221 {
222         int index = workbench_material_get_prepass_shader_index(wpd, use_textures, is_hair);
223         if (e_data.prepass_sh_cache[index] == NULL) {
224                 char *defines = workbench_material_build_defines(wpd, use_textures, is_hair);
225                 char *prepass_vert = workbench_build_prepass_vert(is_hair);
226                 char *prepass_frag = workbench_build_prepass_frag();
227                 e_data.prepass_sh_cache[index] = DRW_shader_create(
228                         prepass_vert, NULL,
229                         prepass_frag, defines);
230                 MEM_freeN(prepass_vert);
231                 MEM_freeN(prepass_frag);
232                 MEM_freeN(defines);
233         }
234         return e_data.prepass_sh_cache[index];
235 }
236
237 static GPUShader *ensure_deferred_composite_shader(WORKBENCH_PrivateData *wpd)
238 {
239         int index = workbench_material_get_composite_shader_index(wpd);
240         if (e_data.composite_sh_cache[index] == NULL) {
241                 char *defines = workbench_material_build_defines(wpd, false, false);
242                 char *composite_frag = workbench_build_composite_frag(wpd);
243                 e_data.composite_sh_cache[index] = DRW_shader_create_fullscreen(composite_frag, defines);
244                 MEM_freeN(composite_frag);
245                 MEM_freeN(defines);
246         }
247         return e_data.composite_sh_cache[index];
248 }
249
250 static GPUShader *ensure_background_shader(WORKBENCH_PrivateData *wpd)
251 {
252         const int index = OBJECT_OUTLINE_ENABLED(wpd) ? 1 : 0;
253         if (e_data.background_sh[index] == NULL) {
254                 const char *defines = (index) ? "#define V3D_SHADING_OBJECT_OUTLINE\n" : NULL;
255                 char *frag = BLI_string_joinN(
256                         datatoc_workbench_data_lib_glsl,
257                         datatoc_workbench_common_lib_glsl,
258                         datatoc_workbench_background_lib_glsl,
259                         datatoc_workbench_object_outline_lib_glsl,
260                         datatoc_workbench_deferred_background_frag_glsl);
261                 e_data.background_sh[index] = DRW_shader_create_fullscreen(frag, defines);
262                 MEM_freeN(frag);
263         }
264         return e_data.background_sh[index];
265 }
266
267 static void select_deferred_shaders(WORKBENCH_PrivateData *wpd)
268 {
269         wpd->prepass_solid_sh = ensure_deferred_prepass_shader(wpd, false, false);
270         wpd->prepass_solid_hair_sh = ensure_deferred_prepass_shader(wpd, false, true);
271         wpd->prepass_texture_sh = ensure_deferred_prepass_shader(wpd, true, false);
272         wpd->prepass_texture_hair_sh = ensure_deferred_prepass_shader(wpd, true, true);
273         wpd->composite_sh = ensure_deferred_composite_shader(wpd);
274         wpd->background_sh = ensure_background_shader(wpd);
275 }
276
277 /* Using Hammersley distribution */
278 static float *create_disk_samples(int num_samples, int num_iterations)
279 {
280         /* vec4 to ensure memory alignment. */
281         const int total_samples = num_samples * num_iterations;
282         float(*texels)[4] = MEM_mallocN(sizeof(float[4]) * total_samples, __func__);
283         const float num_samples_inv = 1.0f / num_samples;
284
285         for (int i = 0; i < total_samples; i++) {
286                 float it_add = (i / num_samples) * 0.499f;
287                 float r = fmodf((i + 0.5f + it_add) * num_samples_inv, 1.0f);
288                 double dphi;
289                 BLI_hammersley_1D(i, &dphi);
290
291                 float phi = (float)dphi * 2.0f * M_PI + it_add;
292                 texels[i][0] = cosf(phi);
293                 texels[i][1] = sinf(phi);
294                 /* This deliberately distribute more samples
295                  * at the center of the disk (and thus the shadow). */
296                 texels[i][2] = r;
297         }
298
299         return (float *)texels;
300 }
301
302 static struct GPUTexture *create_jitter_texture(int num_samples)
303 {
304         float jitter[64 * 64][3];
305         const float num_samples_inv = 1.0f / num_samples;
306
307         for (int i = 0; i < 64 * 64; i++) {
308                 float phi = blue_noise[i][0] * 2.0f * M_PI;
309                 /* This rotate the sample per pixels */
310                 jitter[i][0] = cosf(phi);
311                 jitter[i][1] = sinf(phi);
312                 /* This offset the sample along it's direction axis (reduce banding) */
313                 float bn = blue_noise[i][1] - 0.5f;
314                 CLAMP(bn, -0.499f, 0.499f); /* fix fireflies */
315                 jitter[i][2] = bn * num_samples_inv;
316         }
317
318         UNUSED_VARS(bsdf_split_sum_ggx, btdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx, ltc_disk_integral);
319
320         return DRW_texture_create_2D(64, 64, GPU_RGB16F, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
321 }
322 /* Functions */
323
324
325 static void workbench_init_object_data(DrawData *dd)
326 {
327         WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd;
328         data->object_id = ((e_data.next_object_id++) & 0xff) + 1;
329         data->shadow_bbox_dirty = true;
330 }
331
332 void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
333 {
334         WORKBENCH_FramebufferList *fbl = vedata->fbl;
335         WORKBENCH_StorageList *stl = vedata->stl;
336         WORKBENCH_PassList *psl = vedata->psl;
337         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
338         const DRWContextState *draw_ctx = DRW_context_state_get();
339
340         if (!stl->g_data) {
341                 /* Alloc transient pointers */
342                 stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
343         }
344         if (!stl->effects) {
345                 stl->effects = MEM_callocN(sizeof(*stl->effects), __func__);
346                 workbench_effect_info_init(stl->effects);
347         }
348
349         if (!e_data.next_object_id) {
350                 memset(e_data.prepass_sh_cache,   0, sizeof(e_data.prepass_sh_cache));
351                 memset(e_data.composite_sh_cache, 0, sizeof(e_data.composite_sh_cache));
352                 e_data.next_object_id = 1;
353 #ifdef DEBUG_SHADOW_VOLUME
354                 const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl;
355 #else
356                 const char *shadow_frag = datatoc_gpu_shader_depth_only_frag_glsl;
357 #endif
358                 /* TODO only compile on demand */
359                 e_data.shadow_pass_sh = DRW_shader_create(
360                         datatoc_workbench_shadow_vert_glsl,
361                         datatoc_workbench_shadow_geom_glsl,
362                         shadow_frag,
363                         "#define SHADOW_PASS\n"
364                         "#define DOUBLE_MANIFOLD\n");
365                 e_data.shadow_pass_manifold_sh = DRW_shader_create(
366                         datatoc_workbench_shadow_vert_glsl,
367                         datatoc_workbench_shadow_geom_glsl,
368                         shadow_frag,
369                         "#define SHADOW_PASS\n");
370                 e_data.shadow_fail_sh = DRW_shader_create(
371                         datatoc_workbench_shadow_vert_glsl,
372                         datatoc_workbench_shadow_geom_glsl,
373                         shadow_frag,
374                         "#define SHADOW_FAIL\n"
375                         "#define DOUBLE_MANIFOLD\n");
376                 e_data.shadow_fail_manifold_sh = DRW_shader_create(
377                         datatoc_workbench_shadow_vert_glsl,
378                         datatoc_workbench_shadow_geom_glsl,
379                         shadow_frag,
380                         "#define SHADOW_FAIL\n");
381                 e_data.shadow_caps_sh = DRW_shader_create(
382                         datatoc_workbench_shadow_vert_glsl,
383                         datatoc_workbench_shadow_caps_geom_glsl,
384                         shadow_frag,
385                         "#define SHADOW_FAIL\n"
386                         "#define DOUBLE_MANIFOLD\n");
387                 e_data.shadow_caps_manifold_sh = DRW_shader_create(
388                         datatoc_workbench_shadow_vert_glsl,
389                         datatoc_workbench_shadow_caps_geom_glsl,
390                         shadow_frag,
391                         "#define SHADOW_FAIL\n");
392
393                 e_data.ghost_resolve_sh = DRW_shader_create_fullscreen(datatoc_workbench_ghost_resolve_frag_glsl, NULL);
394         }
395         workbench_volume_engine_init();
396         workbench_fxaa_engine_init();
397         workbench_taa_engine_init(vedata);
398
399         WORKBENCH_PrivateData *wpd = stl->g_data;
400         workbench_private_data_init(wpd);
401
402         {
403                 const float *viewport_size = DRW_viewport_size_get();
404                 const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
405                 const GPUTextureFormat nor_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16 : GPU_RGBA32F;
406                 const GPUTextureFormat comp_tex_format = DRW_state_is_image_render() ? GPU_RGBA16F : GPU_R11F_G11F_B10F;
407                 const GPUTextureFormat id_tex_format = OBJECT_ID_PASS_ENABLED(wpd) ? GPU_R32UI : GPU_R8;
408
409                 e_data.object_id_tx = NULL;
410                 e_data.color_buffer_tx = NULL;
411                 e_data.composite_buffer_tx = NULL;
412                 e_data.normal_buffer_tx = NULL;
413                 e_data.cavity_buffer_tx = NULL;
414
415                 e_data.composite_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], comp_tex_format, &draw_engine_workbench_solid);
416
417                 if (MATDATA_PASS_ENABLED(wpd) || GPU_unused_fb_slot_workaround()) {
418                         e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
419                 }
420                 if (OBJECT_ID_PASS_ENABLED(wpd) || GPU_unused_fb_slot_workaround()) {
421                         e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], id_tex_format, &draw_engine_workbench_solid);
422                 }
423                 if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
424                         e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], nor_tex_format, &draw_engine_workbench_solid);
425                 }
426                 if (CAVITY_ENABLED(wpd)) {
427                         e_data.cavity_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16, &draw_engine_workbench_solid);
428                 }
429
430                 GPU_framebuffer_ensure_config(&fbl->prepass_fb, {
431                         GPU_ATTACHMENT_TEXTURE(dtxl->depth),
432                         GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
433                         GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
434                         GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
435                 });
436                 GPU_framebuffer_ensure_config(&fbl->cavity_fb, {
437                         GPU_ATTACHMENT_NONE,
438                         GPU_ATTACHMENT_TEXTURE(e_data.cavity_buffer_tx),
439                 });
440                 GPU_framebuffer_ensure_config(&fbl->composite_fb, {
441                         GPU_ATTACHMENT_TEXTURE(dtxl->depth),
442                         GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
443                 });
444                 GPU_framebuffer_ensure_config(&fbl->volume_fb, {
445                         GPU_ATTACHMENT_NONE,
446                         GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
447                 });
448
449                 if (!MATDATA_PASS_ENABLED(wpd) && !GPU_unused_fb_slot_workaround()) {
450                         e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
451                 }
452
453                 GPU_framebuffer_ensure_config(&fbl->effect_fb, {
454                         GPU_ATTACHMENT_NONE,
455                         GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
456                 });
457
458                 if (OBJECT_ID_PASS_ENABLED(wpd)) {
459                         GPU_framebuffer_ensure_config(&fbl->id_clear_fb, {
460                                 GPU_ATTACHMENT_NONE,
461                                 GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
462                         });
463                 }
464         }
465
466         {
467                 Scene *scene = draw_ctx->scene;
468                 /* AO Samples Tex */
469                 int num_iterations = workbench_taa_calculate_num_iterations(vedata);
470
471                 const int ssao_samples_single_iteration = scene->display.matcap_ssao_samples;
472                 const int ssao_samples = MIN2(num_iterations * ssao_samples_single_iteration, 500);
473
474                 if (e_data.sampling_ubo && (e_data.cached_sample_num != ssao_samples)) {
475                         DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
476                         DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
477                 }
478
479                 if (e_data.sampling_ubo == NULL) {
480                         float *samples = create_disk_samples(ssao_samples_single_iteration, num_iterations);
481                         e_data.jitter_tx = create_jitter_texture(ssao_samples);
482                         e_data.sampling_ubo = DRW_uniformbuffer_create(sizeof(float[4]) * ssao_samples, samples);
483                         e_data.cached_sample_num = ssao_samples;
484                         MEM_freeN(samples);
485                 }
486         }
487
488         /* Prepass */
489         {
490                 DRWShadingGroup *grp;
491                 const bool do_cull = (draw_ctx->v3d && (draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
492
493                 int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
494                 psl->prepass_pass = DRW_pass_create("Prepass", (do_cull) ? state | DRW_STATE_CULL_BACK : state);
495                 psl->prepass_hair_pass = DRW_pass_create("Prepass", state);
496
497                 psl->ghost_prepass_pass = DRW_pass_create("Prepass Ghost", (do_cull) ? state | DRW_STATE_CULL_BACK : state);
498                 psl->ghost_prepass_hair_pass = DRW_pass_create("Prepass Ghost", state);
499
500                 psl->ghost_resolve_pass = DRW_pass_create("Resolve Ghost Depth", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
501                 grp = DRW_shgroup_create(e_data.ghost_resolve_sh, psl->ghost_resolve_pass);
502                 DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.ghost_depth_tx);
503                 DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
504         }
505
506         {
507                 workbench_aa_create_pass(vedata, &e_data.color_buffer_tx);
508         }
509
510         if (CAVITY_ENABLED(wpd)) {
511                 int state = DRW_STATE_WRITE_COLOR;
512                 GPUShader *shader = workbench_cavity_shader_get(SSAO_ENABLED(wpd), CURVATURE_ENABLED(wpd));
513                 psl->cavity_pass = DRW_pass_create("Cavity", state);
514                 DRWShadingGroup *grp = DRW_shgroup_create(shader, psl->cavity_pass);
515                 DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
516                 DRW_shgroup_uniform_block(grp, "samples_block", e_data.sampling_ubo);
517
518                 if (SSAO_ENABLED(wpd)) {
519                         DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
520                         DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
521                         DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
522                         DRW_shgroup_uniform_vec4(grp, "ssao_params", wpd->ssao_params, 1);
523                         DRW_shgroup_uniform_vec4(grp, "ssao_settings", wpd->ssao_settings, 1);
524                         DRW_shgroup_uniform_mat4(grp, "WinMatrix", wpd->winmat);
525                         DRW_shgroup_uniform_texture(grp, "ssao_jitter", e_data.jitter_tx);
526                 }
527
528                 if (CURVATURE_ENABLED(wpd)) {
529                         DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
530                         DRW_shgroup_uniform_vec2(grp, "curvature_settings", &wpd->world_data.curvature_ridge, 1);
531                 }
532
533                 DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
534         }
535 }
536
537 static void workbench_setup_ghost_framebuffer(WORKBENCH_FramebufferList *fbl)
538 {
539         const float *viewport_size = DRW_viewport_size_get();
540         const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
541
542         e_data.ghost_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_workbench_solid);
543
544         GPU_framebuffer_ensure_config(&fbl->ghost_prepass_fb, {
545                 GPU_ATTACHMENT_TEXTURE(e_data.ghost_depth_tx),
546                 GPU_ATTACHMENT_TEXTURE(e_data.color_buffer_tx),
547                 GPU_ATTACHMENT_TEXTURE(e_data.object_id_tx),
548                 GPU_ATTACHMENT_TEXTURE(e_data.normal_buffer_tx),
549         });
550 }
551
552 void workbench_deferred_engine_free(void)
553 {
554         for (int index = 0; index < MAX_PREPASS_SHADERS; index++) {
555                 DRW_SHADER_FREE_SAFE(e_data.prepass_sh_cache[index]);
556         }
557         for (int index = 0; index < MAX_COMPOSITE_SHADERS; index++) {
558                 DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
559         }
560         for (int index = 0; index < MAX_CAVITY_SHADERS; ++index) {
561                 DRW_SHADER_FREE_SAFE(e_data.cavity_sh[index]);
562         }
563         DRW_SHADER_FREE_SAFE(e_data.ghost_resolve_sh);
564         DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
565         DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
566         DRW_SHADER_FREE_SAFE(e_data.background_sh[0]);
567         DRW_SHADER_FREE_SAFE(e_data.background_sh[1]);
568
569         DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
570         DRW_SHADER_FREE_SAFE(e_data.shadow_pass_manifold_sh);
571         DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
572         DRW_SHADER_FREE_SAFE(e_data.shadow_fail_manifold_sh);
573         DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
574         DRW_SHADER_FREE_SAFE(e_data.shadow_caps_manifold_sh);
575
576         workbench_volume_engine_free();
577         workbench_fxaa_engine_free();
578         workbench_taa_engine_free();
579 }
580
581 static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
582 {
583         DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
584         if (MATDATA_PASS_ENABLED(wpd)) {
585                 DRW_shgroup_uniform_texture_ref(grp, "materialBuffer", &e_data.color_buffer_tx);
586         }
587         else {
588                 DRW_shgroup_uniform_vec3(grp, "materialSingleColor", wpd->shading.single_color, 1);
589         }
590         if (OBJECT_OUTLINE_ENABLED(wpd)) {
591                 DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
592         }
593         if (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd)) {
594                 DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
595         }
596         if (CAVITY_ENABLED(wpd)) {
597                 DRW_shgroup_uniform_texture_ref(grp, "cavityBuffer", &e_data.cavity_buffer_tx);
598         }
599         if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
600                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
601         }
602         if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
603                 DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
604         }
605         if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
606                 BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
607                 DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture);
608         }
609 }
610
611 void workbench_deferred_cache_init(WORKBENCH_Data *vedata)
612 {
613         WORKBENCH_StorageList *stl = vedata->stl;
614         WORKBENCH_PassList *psl = vedata->psl;
615         WORKBENCH_PrivateData *wpd = stl->g_data;
616         DRWShadingGroup *grp;
617         const DRWContextState *draw_ctx = DRW_context_state_get();
618
619         Scene *scene = draw_ctx->scene;
620
621         workbench_volume_cache_init(vedata);
622
623         select_deferred_shaders(wpd);
624
625         /* Background Pass */
626         {
627                 psl->background_pass = DRW_pass_create(
628                         "Background", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
629                 grp = DRW_shgroup_create(wpd->background_sh, psl->background_pass);
630                 DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
631                 DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
632                 if (OBJECT_OUTLINE_ENABLED(wpd)) {
633                         DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
634                 }
635                 DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
636         }
637
638         /* Deferred Mix Pass */
639         {
640                 workbench_private_data_get_light_direction(wpd, e_data.display.light_direction);
641                 studiolight_update_light(wpd, e_data.display.light_direction);
642
643                 float shadow_focus = scene->display.shadow_focus;
644                 /* Clamp to avoid overshadowing and shading errors. */
645                 CLAMP(shadow_focus, 0.0001f, 0.99999f);
646                 shadow_focus = 1.0f - shadow_focus * (1.0f - scene->display.shadow_shift);
647
648                 if (SHADOW_ENABLED(wpd)) {
649                         psl->composite_pass = DRW_pass_create(
650                                 "Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL | DRW_STATE_DEPTH_GREATER);
651                         grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
652                         workbench_composite_uniforms(wpd, grp);
653                         DRW_shgroup_stencil_mask(grp, 0x00);
654                         DRW_shgroup_uniform_float_copy(grp, "lightMultiplier", 1.0f);
655                         DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
656                         DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
657                         DRW_shgroup_uniform_float_copy(grp, "shadowFocus", shadow_focus);
658                         DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
659
660                         /* Stencil Shadow passes. */
661 #ifdef DEBUG_SHADOW_VOLUME
662                         DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
663                         DRWState depth_fail_state = DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE;
664 #else
665                         DRWState depth_pass_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_PASS;
666                         DRWState depth_fail_state = DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL;
667 #endif
668                         psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Pass", depth_pass_state);
669                         psl->shadow_depth_pass_mani_pass = DRW_pass_create("Shadow Pass Mani", depth_pass_state);
670                         psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Fail", depth_fail_state);
671                         psl->shadow_depth_fail_mani_pass = DRW_pass_create("Shadow Fail Mani", depth_fail_state);
672                         psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Fail Caps", depth_fail_state);
673                         psl->shadow_depth_fail_caps_mani_pass = DRW_pass_create("Shadow Fail Caps Mani", depth_fail_state);
674
675 #ifndef DEBUG_SHADOW_VOLUME
676                         grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
677                         DRW_shgroup_stencil_mask(grp, 0xFF);
678                         grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
679                         DRW_shgroup_stencil_mask(grp, 0xFF);
680                         grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
681                         DRW_shgroup_stencil_mask(grp, 0xFF);
682                         grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
683                         DRW_shgroup_stencil_mask(grp, 0xFF);
684                         grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
685                         DRW_shgroup_stencil_mask(grp, 0xFF);
686                         grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh, psl->shadow_depth_fail_caps_mani_pass);
687                         DRW_shgroup_stencil_mask(grp, 0xFF);
688
689                         psl->composite_shadow_pass = DRW_pass_create(
690                                 "Composite Shadow", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL | DRW_STATE_DEPTH_GREATER);
691                         grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass);
692                         DRW_shgroup_stencil_mask(grp, 0x00);
693                         workbench_composite_uniforms(wpd, grp);
694                         DRW_shgroup_uniform_float(grp, "lightMultiplier", &wpd->shadow_multiplier, 1);
695                         DRW_shgroup_uniform_float(grp, "shadowMultiplier", &wpd->shadow_multiplier, 1);
696                         DRW_shgroup_uniform_float_copy(grp, "shadowShift", scene->display.shadow_shift);
697                         DRW_shgroup_uniform_float_copy(grp, "shadowFocus", shadow_focus);
698                         DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
699 #endif
700                 }
701                 else {
702                         psl->composite_pass = DRW_pass_create(
703                                 "Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_GREATER);
704                         grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
705                         workbench_composite_uniforms(wpd, grp);
706                         DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
707                 }
708         }
709 }
710
711 static WORKBENCH_MaterialData *get_or_create_material_data(
712         WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, int color_type)
713 {
714         WORKBENCH_StorageList *stl = vedata->stl;
715         WORKBENCH_PassList *psl = vedata->psl;
716         WORKBENCH_PrivateData *wpd = stl->g_data;
717         WORKBENCH_MaterialData *material;
718         WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
719                 &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
720         WORKBENCH_MaterialData material_template;
721         const bool is_ghost = (ob->dtx & OB_DRAWXRAY);
722
723         /* Solid */
724         workbench_material_update_data(wpd, ob, mat, &material_template);
725         material_template.object_id = OBJECT_ID_PASS_ENABLED(wpd) ? engine_object_data->object_id : 1;
726         material_template.color_type = color_type;
727         material_template.ima = ima;
728         uint hash = workbench_material_get_hash(&material_template, is_ghost);
729
730         material = BLI_ghash_lookup(wpd->material_hash, POINTER_FROM_UINT(hash));
731         if (material == NULL) {
732                 material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
733                 material->shgrp = DRW_shgroup_create(
734                         (color_type == V3D_SHADING_TEXTURE_COLOR) ? wpd->prepass_texture_sh: wpd->prepass_solid_sh,
735                         (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_pass : psl->prepass_pass);
736                 workbench_material_copy(material, &material_template);
737                 DRW_shgroup_stencil_mask(material->shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
738                 DRW_shgroup_uniform_int(material->shgrp, "object_id", &material->object_id, 1);
739                 workbench_material_shgroup_uniform(wpd, material->shgrp, material, ob, true, true);
740
741                 BLI_ghash_insert(wpd->material_hash, POINTER_FROM_UINT(hash), material);
742         }
743         return material;
744 }
745
746 static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, Object *ob)
747 {
748         WORKBENCH_StorageList *stl = vedata->stl;
749         WORKBENCH_PassList *psl = vedata->psl;
750         WORKBENCH_PrivateData *wpd = stl->g_data;
751
752         for (ModifierData *md = ob->modifiers.first; md; md = md->next) {
753                 if (md->type != eModifierType_ParticleSystem) {
754                         continue;
755                 }
756                 ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
757                 if (!psys_check_enabled(ob, psys, false)) {
758                         continue;
759                 }
760                 if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
761                         continue;
762                 }
763                 ParticleSettings *part = psys->part;
764                 const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
765
766                 if (draw_as == PART_DRAW_PATH) {
767                         Image *image = NULL;
768                         Material *mat = give_current_material(ob, part->omat);
769                         ED_object_get_active_image(ob, part->omat, &image, NULL, NULL, NULL);
770                         int color_type = workbench_material_determine_color_type(wpd, image, ob);
771                         WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, mat, image, color_type);
772
773                         struct GPUShader *shader = (color_type != V3D_SHADING_TEXTURE_COLOR) ?
774                                 wpd->prepass_solid_hair_sh :
775                                 wpd->prepass_texture_hair_sh;
776                         DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
777                                 ob, psys, md,
778                                 (ob->dtx & OB_DRAWXRAY) ? psl->ghost_prepass_hair_pass : psl->prepass_hair_pass,
779                                 shader);
780                         DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
781                         DRW_shgroup_uniform_int(shgrp, "object_id", &material->object_id, 1);
782                         workbench_material_shgroup_uniform(wpd, shgrp, material, ob, true, true);
783                 }
784         }
785 }
786
787 void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
788 {
789         WORKBENCH_StorageList *stl = vedata->stl;
790         WORKBENCH_PassList *psl = vedata->psl;
791         WORKBENCH_PrivateData *wpd = stl->g_data;
792         const DRWContextState *draw_ctx = DRW_context_state_get();
793         Scene *scene = draw_ctx->scene;
794
795         if (!DRW_object_is_renderable(ob))
796                 return;
797
798         if (ob->type == OB_MESH) {
799                 workbench_cache_populate_particles(vedata, ob);
800         }
801
802         ModifierData *md;
803         if (((ob->base_flag & BASE_FROMDUPLI) == 0) &&
804             (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
805             (modifier_isEnabled(scene, md, eModifierMode_Realtime)) &&
806             (((SmokeModifierData *)md)->domain != NULL))
807         {
808                 workbench_volume_cache_populate(vedata, scene, ob, md);
809                 return; /* Do not draw solid in this case. */
810         }
811
812         if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
813                 return;
814         }
815         if (ob->dt < OB_SOLID) {
816                 return;
817         }
818
819         WORKBENCH_MaterialData *material;
820         if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
821                 const bool is_active = (ob == draw_ctx->obact);
822                 const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
823                 const bool use_hide = is_active && DRW_object_use_hide_faces(ob);
824                 const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
825                 const Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
826
827                 if (!is_sculpt_mode && me && me->mloopuv && TEXTURE_DRAWING_ENABLED(wpd)) {
828                         /* Draw textured */
829                         struct GPUBatch **geom_array = DRW_cache_mesh_surface_texpaint_get(ob);
830                         for (int i = 0; i < materials_len; i++) {
831                                 if (geom_array != NULL && geom_array[i] != NULL) {
832                                         Material *mat = give_current_material(ob, i + 1);
833                                         Image *image;
834                                         ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
835                                         int color_type = workbench_material_determine_color_type(wpd, image, ob);
836                                         material = get_or_create_material_data(vedata, ob, mat, image, color_type);
837                                         DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob);
838                                 }
839                         }
840                 }
841                 else if (ELEM(wpd->shading.color_type,
842                               V3D_SHADING_SINGLE_COLOR, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_RANDOM_COLOR)) {
843                         /* Draw solid color */
844                         material = get_or_create_material_data(vedata, ob, NULL, NULL, wpd->shading.color_type);
845                         if (is_sculpt_mode) {
846                                 DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
847                         }
848                         else {
849                                 struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
850                                 if (geom) {
851                                         DRW_shgroup_call_object_add(material->shgrp, geom, ob);
852                                 }
853                         }
854                 }
855                 else {
856                         /* Draw material color */
857                         if (is_sculpt_mode) {
858                                 /* Multiple materials are not supported in sculpt mode yet. */
859                                 Material *mat = give_current_material(ob, 1);
860                                 material = get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR);
861                                 DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat);
862                         }
863                         else {
864                                 struct GPUBatch **geoms;
865                                 struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
866                                 memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
867
868                                 geoms = DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len, NULL, NULL, NULL);
869                                 for (int i = 0; i < materials_len; ++i) {
870                                         if (geoms != NULL && geoms[i] != NULL) {
871                                                 Material *mat = give_current_material(ob, i + 1);
872                                                 material = get_or_create_material_data(vedata, ob, mat, NULL, V3D_SHADING_MATERIAL_COLOR);
873                                                 DRW_shgroup_call_object_add(material->shgrp, geoms[i], ob);
874                                         }
875                                 }
876                         }
877                 }
878
879                 if (SHADOW_ENABLED(wpd) && (ob->display.flag & OB_SHOW_SHADOW)) {
880                         bool is_manifold;
881                         struct GPUBatch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold);
882                         if (geom_shadow) {
883                                 if (is_sculpt_mode || use_hide) {
884                                         /* Currently unsupported in sculpt mode. We could revert to the slow
885                                          * method in this case but I'm not sure if it's a good idea given that
886                                          * sculpted meshes are heavy to begin with. */
887                                         // DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat);
888                                 }
889                                 else {
890                                         WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure(
891                                                 &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL);
892
893                                         if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) {
894
895                                                 invert_m4_m4(ob->imat, ob->obmat);
896                                                 mul_v3_mat3_m4v3(engine_object_data->shadow_dir, ob->imat, e_data.display.light_direction);
897
898                                                 DRWShadingGroup *grp;
899                                                 bool use_shadow_pass_technique = !studiolight_camera_in_object_shadow(wpd, ob, engine_object_data);
900
901                                                 if (use_shadow_pass_technique) {
902                                                         if (is_manifold) {
903                                                                 grp = DRW_shgroup_create(e_data.shadow_pass_manifold_sh, psl->shadow_depth_pass_mani_pass);
904                                                         }
905                                                         else {
906                                                                 grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
907                                                         }
908                                                         DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
909                                                         DRW_shgroup_uniform_float_copy(grp, "lightDistance", 1e5f);
910                                                         DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
911 #ifdef DEBUG_SHADOW_VOLUME
912                                                         DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){1.0f, 0.0f, 0.0f, 1.0f});
913 #endif
914                                                 }
915                                                 else {
916                                                         float extrude_distance = studiolight_object_shadow_distance(wpd, ob, engine_object_data);
917
918                                                         /* TODO(fclem): only use caps if they are in the view frustum. */
919                                                         const bool need_caps = true;
920                                                         if (need_caps) {
921                                                                 if (is_manifold) {
922                                                                         grp = DRW_shgroup_create(e_data.shadow_caps_manifold_sh, psl->shadow_depth_fail_caps_mani_pass);
923                                                                 }
924                                                                 else {
925                                                                         grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
926                                                                 }
927                                                                 DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
928                                                                 DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
929                                                                 DRW_shgroup_call_add(grp, DRW_cache_object_surface_get(ob), ob->obmat);
930                                                         }
931
932                                                         if (is_manifold) {
933                                                                 grp = DRW_shgroup_create(e_data.shadow_fail_manifold_sh, psl->shadow_depth_fail_mani_pass);
934                                                         }
935                                                         else {
936                                                                 grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
937                                                         }
938                                                         DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
939                                                         DRW_shgroup_uniform_float_copy(grp, "lightDistance", extrude_distance);
940                                                         DRW_shgroup_call_add(grp, geom_shadow, ob->obmat);
941 #ifdef DEBUG_SHADOW_VOLUME
942                                                         DRW_debug_bbox(&engine_object_data->shadow_bbox, (float[4]){0.0f, 1.0f, 0.0f, 1.0f});
943 #endif
944                                                 }
945                                         }
946                                 }
947                         }
948                 }
949         }
950 }
951
952 void workbench_deferred_cache_finish(WORKBENCH_Data *UNUSED(vedata))
953 {
954 }
955
956 void workbench_deferred_draw_background(WORKBENCH_Data *vedata)
957 {
958         WORKBENCH_StorageList *stl = vedata->stl;
959         WORKBENCH_FramebufferList *fbl = vedata->fbl;
960         WORKBENCH_PrivateData *wpd = stl->g_data;
961         const float clear_depth = 1.0f;
962         const float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
963         uint clear_stencil = 0x00;
964
965         DRW_stats_group_start("Clear Background");
966
967         if (OBJECT_ID_PASS_ENABLED(wpd)) {
968                 /* From all the color buffers, only object id needs to be cleared. */
969                 GPU_framebuffer_bind(fbl->id_clear_fb);
970                 GPU_framebuffer_clear_color(fbl->id_clear_fb, clear_color);
971         }
972
973         GPU_framebuffer_bind(fbl->prepass_fb);
974         int clear_bits = GPU_DEPTH_BIT;
975         SET_FLAG_FROM_TEST(clear_bits, SHADOW_ENABLED(wpd), GPU_STENCIL_BIT);
976         GPU_framebuffer_clear(fbl->prepass_fb, clear_bits, clear_color, clear_depth, clear_stencil);
977         DRW_stats_group_end();
978 }
979
980 void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
981 {
982         WORKBENCH_PassList *psl = vedata->psl;
983         WORKBENCH_StorageList *stl = vedata->stl;
984         WORKBENCH_FramebufferList *fbl = vedata->fbl;
985         WORKBENCH_PrivateData *wpd = stl->g_data;
986         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
987
988         if (TAA_ENABLED(wpd)) {
989                 workbench_taa_draw_scene_start(vedata);
990         }
991
992         /* clear in background */
993         GPU_framebuffer_bind(fbl->prepass_fb);
994         DRW_draw_pass(psl->prepass_pass);
995         DRW_draw_pass(psl->prepass_hair_pass);
996
997         if (GHOST_ENABLED(psl)) {
998                 /* meh, late init to not request a depth buffer we won't use. */
999                 workbench_setup_ghost_framebuffer(fbl);
1000
1001                 GPU_framebuffer_bind(fbl->ghost_prepass_fb);
1002                 GPU_framebuffer_clear_depth(fbl->ghost_prepass_fb, 1.0f);
1003                 DRW_draw_pass(psl->ghost_prepass_pass);
1004                 DRW_draw_pass(psl->ghost_prepass_hair_pass);
1005
1006                 GPU_framebuffer_bind(dfbl->depth_only_fb);
1007                 DRW_draw_pass(psl->ghost_resolve_pass);
1008         }
1009
1010         if (CAVITY_ENABLED(wpd)) {
1011                 GPU_framebuffer_bind(fbl->cavity_fb);
1012                 DRW_draw_pass(psl->cavity_pass);
1013         }
1014
1015         if (SHADOW_ENABLED(wpd)) {
1016 #ifdef DEBUG_SHADOW_VOLUME
1017                 GPU_framebuffer_bind(fbl->composite_fb);
1018                 DRW_draw_pass(psl->composite_pass);
1019 #else
1020                 GPU_framebuffer_bind(dfbl->depth_only_fb);
1021 #endif
1022                 DRW_draw_pass(psl->shadow_depth_pass_pass);
1023                 DRW_draw_pass(psl->shadow_depth_pass_mani_pass);
1024                 DRW_draw_pass(psl->shadow_depth_fail_pass);
1025                 DRW_draw_pass(psl->shadow_depth_fail_mani_pass);
1026                 DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
1027                 DRW_draw_pass(psl->shadow_depth_fail_caps_mani_pass);
1028
1029                 if (GHOST_ENABLED(psl)) {
1030                         /* We need to set the stencil buffer to 0 where Ghost objects
1031                          * else they will get shadow and even badly shadowed. */
1032                         DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
1033                         DRW_pass_state_set(psl->ghost_prepass_hair_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
1034
1035                         DRW_draw_pass(psl->ghost_prepass_pass);
1036                         DRW_draw_pass(psl->ghost_prepass_hair_pass);
1037                 }
1038 #ifndef DEBUG_SHADOW_VOLUME
1039                 GPU_framebuffer_bind(fbl->composite_fb);
1040                 DRW_draw_pass(psl->composite_pass);
1041                 DRW_draw_pass(psl->composite_shadow_pass);
1042 #endif
1043         }
1044         else {
1045                 GPU_framebuffer_bind(fbl->composite_fb);
1046                 DRW_draw_pass(psl->composite_pass);
1047         }
1048
1049         /* TODO(fclem): only enable when needed (when there is overlays). */
1050         if (GHOST_ENABLED(psl)) {
1051                 /* In order to not draw on top of ghost objects, we clear the stencil
1052                  * to 0xFF and the ghost object to 0x00 and only draw overlays on top if
1053                  * stencil is not 0. */
1054                 GPU_framebuffer_bind(dfbl->depth_only_fb);
1055                 GPU_framebuffer_clear_stencil(dfbl->depth_only_fb, 0xFF);
1056
1057                 DRW_pass_state_set(psl->ghost_prepass_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
1058                 DRW_pass_state_set(psl->ghost_prepass_hair_pass, DRW_STATE_DEPTH_EQUAL | DRW_STATE_WRITE_STENCIL);
1059
1060                 DRW_draw_pass(psl->ghost_prepass_pass);
1061                 DRW_draw_pass(psl->ghost_prepass_hair_pass);
1062         }
1063
1064         GPU_framebuffer_bind(fbl->composite_fb);
1065         DRW_draw_pass(psl->background_pass);
1066
1067         if (wpd->volumes_do) {
1068                 GPU_framebuffer_bind(fbl->volume_fb);
1069                 DRW_draw_pass(psl->volume_pass);
1070         }
1071
1072         workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx);
1073 }
1074
1075 void workbench_deferred_draw_finish(WORKBENCH_Data *vedata)
1076 {
1077         WORKBENCH_StorageList *stl = vedata->stl;
1078         WORKBENCH_PrivateData *wpd = stl->g_data;
1079
1080         workbench_private_data_free(wpd);
1081         workbench_volume_smoke_textures_free(wpd);
1082 }