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