Object Mode: Add to EvaluationContext & DRWContextState
[blender.git] / source / blender / draw / engines / clay / clay_engine.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 #include "BLI_utildefines.h"
23 #include "BLI_dynstr.h"
24 #include "BLI_rand.h"
25
26 #include "DNA_particle_types.h"
27
28 #include "BKE_icons.h"
29 #include "BKE_idprop.h"
30 #include "BKE_main.h"
31 #include "BKE_particle.h"
32
33 #include "GPU_shader.h"
34
35 #include "IMB_imbuf.h"
36 #include "IMB_imbuf_types.h"
37
38 #include "UI_resources.h"
39 #include "UI_interface_icons.h"
40
41 #include "DRW_render.h"
42
43 #include "clay_engine.h"
44
45 #ifdef WITH_CLAY_ENGINE
46 #include "../eevee/eevee_lut.h" /* TODO find somewhere to share blue noise Table */
47
48 /* Shaders */
49
50 #define CLAY_ENGINE "BLENDER_CLAY"
51
52 #define MAX_CLAY_MAT 512 /* 512 = 9 bit material id */
53
54 #define SHADER_DEFINES \
55         "#define MAX_MATERIAL " STRINGIFY(MAX_CLAY_MAT) "\n" \
56         "#define USE_ROTATION\n" \
57         "#define USE_AO\n" \
58         "#define USE_HSV\n"
59
60 extern char datatoc_clay_frag_glsl[];
61 extern char datatoc_clay_vert_glsl[];
62 extern char datatoc_clay_particle_vert_glsl[];
63 extern char datatoc_clay_particle_strand_frag_glsl[];
64 extern char datatoc_ssao_alchemy_glsl[];
65
66 /* *********** LISTS *********** */
67
68 /**
69  * UBOs data needs to be 16 byte aligned (size of vec4)
70  *
71  * Reminder: float, int, bool are 4 bytes
72  *
73  * \note struct is expected to be initialized with all pad-bits zero'd
74  * so we can use 'memcmp' to check for duplicates. Possibly hash data later.
75  */
76 typedef struct CLAY_UBO_Material {
77         float ssao_params_var[4];
78         /* - 16 -*/
79         float matcap_hsv[3];
80         float matcap_id; /* even float encoding have enough precision */
81         /* - 16 -*/
82         float matcap_rot[2];
83         float pad[2]; /* ensure 16 bytes alignement */
84 } CLAY_UBO_Material; /* 48 bytes */
85 BLI_STATIC_ASSERT_ALIGN(CLAY_UBO_Material, 16)
86
87 typedef struct CLAY_HAIR_UBO_Material {
88         float hair_randomness;
89         float matcap_id;
90         float matcap_rot[2];
91         float matcap_hsv[3];
92         float pad;
93 } CLAY_HAIR_UBO_Material; /* 32 bytes */
94 BLI_STATIC_ASSERT_ALIGN(CLAY_HAIR_UBO_Material, 16)
95
96 typedef struct CLAY_UBO_Storage {
97         CLAY_UBO_Material materials[MAX_CLAY_MAT];
98 } CLAY_UBO_Storage;
99
100 typedef struct CLAY_HAIR_UBO_Storage {
101         CLAY_HAIR_UBO_Material materials[MAX_CLAY_MAT];
102 } CLAY_HAIR_UBO_Storage;
103
104 /* GPUViewport.storage
105  * Is freed everytime the viewport engine changes */
106 typedef struct CLAY_Storage {
107         /* Materials Parameter UBO */
108         CLAY_UBO_Storage mat_storage;
109         CLAY_HAIR_UBO_Storage hair_mat_storage;
110         int ubo_current_id;
111         int hair_ubo_current_id;
112         DRWShadingGroup *shgrps[MAX_CLAY_MAT];
113         DRWShadingGroup *shgrps_flat[MAX_CLAY_MAT];
114         DRWShadingGroup *hair_shgrps[MAX_CLAY_MAT];
115 } CLAY_Storage;
116
117 typedef struct CLAY_StorageList {
118         struct CLAY_Storage *storage;
119         struct GPUUniformBuffer *mat_ubo;
120         struct GPUUniformBuffer *hair_mat_ubo;
121         struct CLAY_PrivateData *g_data;
122 } CLAY_StorageList;
123
124 typedef struct CLAY_FramebufferList {
125         /* default */
126         struct GPUFrameBuffer *default_fb;
127         /* engine specific */
128         struct GPUFrameBuffer *dupli_depth;
129 } CLAY_FramebufferList;
130
131 typedef struct CLAY_PassList {
132         struct DRWPass *depth_pass;
133         struct DRWPass *depth_pass_cull;
134         struct DRWPass *clay_pass;
135         struct DRWPass *clay_pass_flat;
136         struct DRWPass *hair_pass;
137 } CLAY_PassList;
138
139 typedef struct CLAY_Data {
140         void *engine_type;
141         CLAY_FramebufferList *fbl;
142         DRWViewportEmptyList *txl;
143         CLAY_PassList *psl;
144         CLAY_StorageList *stl;
145 } CLAY_Data;
146
147 typedef struct CLAY_ViewLayerData {
148         struct GPUTexture *jitter_tx;
149         struct GPUUniformBuffer *sampling_ubo;
150         int cached_sample_num;
151 } CLAY_ViewLayerData;
152
153 /* *********** STATIC *********** */
154
155 static struct {
156         /* Depth Pre Pass */
157         struct GPUShader *depth_sh;
158         /* Shading Pass */
159         struct GPUShader *clay_sh;
160         struct GPUShader *clay_flat_sh;
161         struct GPUShader *hair_sh;
162
163         /* Matcap textures */
164         struct GPUTexture *matcap_array;
165         float matcap_colors[24][3];
166
167         /* Ssao */
168         float winmat[4][4];
169         float viewvecs[3][4];
170         float ssao_params[4];
171
172         /* Just a serie of int from 0 to MAX_CLAY_MAT-1 */
173         int ubo_mat_idxs[MAX_CLAY_MAT];
174
175         /* engine specific */
176         struct GPUTexture *depth_dup;
177 } e_data = {NULL}; /* Engine data */
178
179 typedef struct CLAY_PrivateData {
180         DRWShadingGroup *depth_shgrp;
181         DRWShadingGroup *depth_shgrp_select;
182         DRWShadingGroup *depth_shgrp_active;
183         DRWShadingGroup *depth_shgrp_cull;
184         DRWShadingGroup *depth_shgrp_cull_select;
185         DRWShadingGroup *depth_shgrp_cull_active;
186         bool enable_ao;
187 } CLAY_PrivateData; /* Transient data */
188
189 /* Functions */
190
191 static void clay_view_layer_data_free(void *storage)
192 {
193         CLAY_ViewLayerData *sldata = (CLAY_ViewLayerData *)storage;
194
195         DRW_UBO_FREE_SAFE(sldata->sampling_ubo);
196         DRW_TEXTURE_FREE_SAFE(sldata->jitter_tx);
197 }
198
199 static CLAY_ViewLayerData *CLAY_view_layer_data_get(void)
200 {
201         CLAY_ViewLayerData **sldata = (CLAY_ViewLayerData **)DRW_view_layer_engine_data_ensure(&draw_engine_clay_type, &clay_view_layer_data_free);
202
203         if (*sldata == NULL) {
204                 *sldata = MEM_callocN(sizeof(**sldata), "CLAY_ViewLayerData");
205         }
206
207         return *sldata;
208 }
209
210 static void add_icon_to_rect(PreviewImage *prv, float *final_rect, int layer)
211 {
212         int image_size = prv->w[0] * prv->h[0];
213         float *new_rect = &final_rect[image_size * 4 * layer];
214
215         IMB_buffer_float_from_byte(new_rect, (unsigned char *)prv->rect[0], IB_PROFILE_SRGB, IB_PROFILE_SRGB,
216                                    false, prv->w[0], prv->h[0], prv->w[0], prv->w[0]);
217
218         /* Find overall color */
219         for (int y = 0; y < 4; ++y)     {
220                 for (int x = 0; x < 4; ++x) {
221                         e_data.matcap_colors[layer][0] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 0];
222                         e_data.matcap_colors[layer][1] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 1];
223                         e_data.matcap_colors[layer][2] += new_rect[y * 512 * 128 * 4 + x * 128 * 4 + 2];
224                 }
225         }
226
227         e_data.matcap_colors[layer][0] /= 16.0f * 2.0f; /* the * 2 is to darken for shadows */
228         e_data.matcap_colors[layer][1] /= 16.0f * 2.0f;
229         e_data.matcap_colors[layer][2] /= 16.0f * 2.0f;
230 }
231
232 static struct GPUTexture *load_matcaps(PreviewImage *prv[24], int nbr)
233 {
234         struct GPUTexture *tex;
235         int w = prv[0]->w[0];
236         int h = prv[0]->h[0];
237         float *final_rect = MEM_callocN(sizeof(float) * 4 * w * h * nbr, "Clay Matcap array rect");
238
239         for (int i = 0; i < nbr; ++i) {
240                 add_icon_to_rect(prv[i], final_rect, i);
241                 BKE_previewimg_free(&prv[i]);
242         }
243
244         tex = DRW_texture_create_2D_array(w, h, nbr, DRW_TEX_RGBA_8, DRW_TEX_FILTER, final_rect);
245         MEM_freeN(final_rect);
246
247         return tex;
248 }
249
250 static int matcap_to_index(int matcap)
251 {
252         switch (matcap) {
253                 case ICON_MATCAP_01: return 0;
254                 case ICON_MATCAP_02: return 1;
255                 case ICON_MATCAP_03: return 2;
256                 case ICON_MATCAP_04: return 3;
257                 case ICON_MATCAP_05: return 4;
258                 case ICON_MATCAP_06: return 5;
259                 case ICON_MATCAP_07: return 6;
260                 case ICON_MATCAP_08: return 7;
261                 case ICON_MATCAP_09: return 8;
262                 case ICON_MATCAP_10: return 9;
263                 case ICON_MATCAP_11: return 10;
264                 case ICON_MATCAP_12: return 11;
265                 case ICON_MATCAP_13: return 12;
266                 case ICON_MATCAP_14: return 13;
267                 case ICON_MATCAP_15: return 14;
268                 case ICON_MATCAP_16: return 15;
269                 case ICON_MATCAP_17: return 16;
270                 case ICON_MATCAP_18: return 17;
271                 case ICON_MATCAP_19: return 18;
272                 case ICON_MATCAP_20: return 19;
273                 case ICON_MATCAP_21: return 20;
274                 case ICON_MATCAP_22: return 21;
275                 case ICON_MATCAP_23: return 22;
276                 case ICON_MATCAP_24: return 23;
277         }
278         BLI_assert(!"Should not happen");
279         return 0;
280 }
281
282 /* Using Hammersley distribution */
283 static float *create_disk_samples(int num_samples)
284 {
285         /* vec4 to ensure memory alignment. */
286         float (*texels)[4] = MEM_mallocN(sizeof(float[4]) * num_samples, "concentric_tex");
287         const float num_samples_inv = 1.0f / num_samples;
288
289         for (int i = 0; i < num_samples; i++) {
290                 float r = (i + 0.5f) * num_samples_inv;
291                 double dphi;
292                 BLI_hammersley_1D(i, &dphi);
293
294                 float phi = (float)dphi * 2.0f * M_PI;
295                 texels[i][0] = cosf(phi);
296                 texels[i][1] = sinf(phi);
297                 /* This deliberatly distribute more samples
298                  * at the center of the disk (and thus the shadow). */
299                 texels[i][2] = r;
300         }
301
302         return (float *)texels;
303 }
304
305 static struct GPUTexture *create_jitter_texture(int num_samples)
306 {
307         float jitter[64 * 64][3];
308         const float num_samples_inv = 1.0f / num_samples;
309
310         for (int i = 0; i < 64 * 64; i++) {
311                 float phi = blue_noise[i][0] * 2.0f * M_PI;
312                 /* This rotate the sample per pixels */
313                 jitter[i][0] = cosf(phi);
314                 jitter[i][1] = sinf(phi);
315                 /* This offset the sample along it's direction axis (reduce banding) */
316                 float bn = blue_noise[i][1] - 0.5f;
317                 CLAMP(bn, -0.499f, 0.499f); /* fix fireflies */
318                 jitter[i][2] = bn * num_samples_inv;
319         }
320
321         UNUSED_VARS(bsdf_split_sum_ggx, btdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx, ltc_disk_integral);
322
323         return DRW_texture_create_2D(64, 64, DRW_TEX_RGB_16, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
324 }
325
326 static void clay_engine_init(void *vedata)
327 {
328         CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
329         CLAY_FramebufferList *fbl = ((CLAY_Data *)vedata)->fbl;
330         CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get();
331
332         /* Create Texture Array */
333         if (!e_data.matcap_array) {
334                 PreviewImage *prv[24]; /* For now use all of the 24 internal matcaps */
335
336                 /* TODO only load used matcaps */
337                 prv[0]  = UI_icon_to_preview(ICON_MATCAP_01);
338                 prv[1]  = UI_icon_to_preview(ICON_MATCAP_02);
339                 prv[2]  = UI_icon_to_preview(ICON_MATCAP_03);
340                 prv[3]  = UI_icon_to_preview(ICON_MATCAP_04);
341                 prv[4]  = UI_icon_to_preview(ICON_MATCAP_05);
342                 prv[5]  = UI_icon_to_preview(ICON_MATCAP_06);
343                 prv[6]  = UI_icon_to_preview(ICON_MATCAP_07);
344                 prv[7]  = UI_icon_to_preview(ICON_MATCAP_08);
345                 prv[8]  = UI_icon_to_preview(ICON_MATCAP_09);
346                 prv[9]  = UI_icon_to_preview(ICON_MATCAP_10);
347                 prv[10] = UI_icon_to_preview(ICON_MATCAP_11);
348                 prv[11] = UI_icon_to_preview(ICON_MATCAP_12);
349                 prv[12] = UI_icon_to_preview(ICON_MATCAP_13);
350                 prv[13] = UI_icon_to_preview(ICON_MATCAP_14);
351                 prv[14] = UI_icon_to_preview(ICON_MATCAP_15);
352                 prv[15] = UI_icon_to_preview(ICON_MATCAP_16);
353                 prv[16] = UI_icon_to_preview(ICON_MATCAP_17);
354                 prv[17] = UI_icon_to_preview(ICON_MATCAP_18);
355                 prv[18] = UI_icon_to_preview(ICON_MATCAP_19);
356                 prv[19] = UI_icon_to_preview(ICON_MATCAP_20);
357                 prv[20] = UI_icon_to_preview(ICON_MATCAP_21);
358                 prv[21] = UI_icon_to_preview(ICON_MATCAP_22);
359                 prv[22] = UI_icon_to_preview(ICON_MATCAP_23);
360                 prv[23] = UI_icon_to_preview(ICON_MATCAP_24);
361
362                 e_data.matcap_array = load_matcaps(prv, 24);
363         }
364
365         /* Depth prepass */
366         if (!e_data.depth_sh) {
367                 e_data.depth_sh = DRW_shader_create_3D_depth_only();
368         }
369
370         /* Shading pass */
371         if (!e_data.clay_sh) {
372                 DynStr *ds = BLI_dynstr_new();
373                 char *matcap_with_ao;
374
375                 BLI_dynstr_append(ds, datatoc_clay_frag_glsl);
376                 BLI_dynstr_append(ds, datatoc_ssao_alchemy_glsl);
377
378                 matcap_with_ao = BLI_dynstr_get_cstring(ds);
379
380                 e_data.clay_sh = DRW_shader_create(
381                         datatoc_clay_vert_glsl, NULL, matcap_with_ao,
382                         SHADER_DEFINES);
383                 e_data.clay_flat_sh = DRW_shader_create(
384                         datatoc_clay_vert_glsl, NULL, matcap_with_ao,
385                         SHADER_DEFINES
386                         "#define USE_FLAT_NORMAL\n");
387
388                 BLI_dynstr_free(ds);
389                 MEM_freeN(matcap_with_ao);
390         }
391
392         if (!e_data.hair_sh) {
393                 e_data.hair_sh = DRW_shader_create(
394                         datatoc_clay_particle_vert_glsl, NULL, datatoc_clay_particle_strand_frag_glsl,
395                         "#define MAX_MATERIAL 512\n");
396         }
397
398         if (!stl->storage) {
399                 stl->storage = MEM_callocN(sizeof(CLAY_Storage), "CLAY_Storage");
400         }
401
402         if (!stl->mat_ubo) {
403                 stl->mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_UBO_Storage), NULL);
404         }
405
406         if (!stl->hair_mat_ubo) {
407                 stl->hair_mat_ubo = DRW_uniformbuffer_create(sizeof(CLAY_HAIR_UBO_Storage), NULL);
408         }
409
410         if (e_data.ubo_mat_idxs[1] == 0) {
411                 /* Just int to have pointers to them */
412                 for (int i = 0; i < MAX_CLAY_MAT; ++i) {
413                         e_data.ubo_mat_idxs[i] = i;
414                 }
415         }
416
417         if (DRW_state_is_fbo()) {
418                 const float *viewport_size = DRW_viewport_size_get();
419                 DRWFboTexture tex = {&e_data.depth_dup, DRW_TEX_DEPTH_24_STENCIL_8, DRW_TEX_TEMP};
420                 DRW_framebuffer_init(&fbl->dupli_depth, &draw_engine_clay_type,
421                                      (int)viewport_size[0], (int)viewport_size[1],
422                                      &tex, 1);
423         }
424
425         /* SSAO setup */
426         {
427                 const DRWContextState *draw_ctx = DRW_context_state_get();
428                 ViewLayer *view_layer = draw_ctx->view_layer;
429                 IDProperty *props = BKE_view_layer_engine_evaluated_get(
430                         view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_CLAY);
431                 int ssao_samples = BKE_collection_engine_property_value_get_int(props, "ssao_samples");
432
433                 float invproj[4][4];
434                 float dfdyfacs[2];
435                 const bool is_persp = DRW_viewport_is_persp_get();
436                 /* view vectors for the corners of the view frustum.
437                  * Can be used to recreate the world space position easily */
438                 float viewvecs[3][4] = {
439                     {-1.0f, -1.0f, -1.0f, 1.0f},
440                     {1.0f, -1.0f, -1.0f, 1.0f},
441                     {-1.0f, 1.0f, -1.0f, 1.0f}
442                 };
443                 int i;
444                 const float *size = DRW_viewport_size_get();
445
446                 DRW_state_dfdy_factors_get(dfdyfacs);
447
448                 e_data.ssao_params[0] = ssao_samples;
449                 e_data.ssao_params[1] = size[0] / 64.0;
450                 e_data.ssao_params[2] = size[1] / 64.0;
451                 e_data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
452
453                 /* invert the view matrix */
454                 DRW_viewport_matrix_get(e_data.winmat, DRW_MAT_WIN);
455                 invert_m4_m4(invproj, e_data.winmat);
456
457                 /* convert the view vectors to view space */
458                 for (i = 0; i < 3; i++) {
459                         mul_m4_v4(invproj, viewvecs[i]);
460                         /* normalized trick see:
461                          * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
462                         mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
463                         if (is_persp)
464                                 mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
465                         viewvecs[i][3] = 1.0;
466
467                         copy_v4_v4(e_data.viewvecs[i], viewvecs[i]);
468                 }
469
470                 /* we need to store the differences */
471                 e_data.viewvecs[1][0] -= e_data.viewvecs[0][0];
472                 e_data.viewvecs[1][1] = e_data.viewvecs[2][1] - e_data.viewvecs[0][1];
473
474                 /* calculate a depth offset as well */
475                 if (!is_persp) {
476                         float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
477                         mul_m4_v4(invproj, vec_far);
478                         mul_v3_fl(vec_far, 1.0f / vec_far[3]);
479                         e_data.viewvecs[1][2] = vec_far[2] - e_data.viewvecs[0][2];
480                 }
481
482                 /* AO Samples Tex */
483                 if (sldata->sampling_ubo && (sldata->cached_sample_num != ssao_samples)) {
484                         DRW_UBO_FREE_SAFE(sldata->sampling_ubo);
485                         DRW_TEXTURE_FREE_SAFE(sldata->jitter_tx);
486                 }
487
488                 if (sldata->sampling_ubo == NULL) {
489                         float *samples = create_disk_samples(ssao_samples);
490                         sldata->jitter_tx = create_jitter_texture(ssao_samples);
491                         sldata->sampling_ubo = DRW_uniformbuffer_create(sizeof(float[4]) * ssao_samples, samples);
492                         sldata->cached_sample_num = ssao_samples;
493                         MEM_freeN(samples);
494                 }
495         }
496 }
497
498 static DRWShadingGroup *CLAY_shgroup_create(CLAY_Data *vedata, DRWPass *pass, int *material_id, bool use_flat)
499 {
500         CLAY_StorageList *stl = vedata->stl;
501         CLAY_ViewLayerData *sldata = CLAY_view_layer_data_get();
502         DRWShadingGroup *grp = DRW_shgroup_create(use_flat ? e_data.clay_flat_sh : e_data.clay_sh, pass);
503
504         DRW_shgroup_uniform_vec2(grp, "screenres", DRW_viewport_size_get(), 1);
505         DRW_shgroup_uniform_buffer(grp, "depthtex", &e_data.depth_dup);
506         DRW_shgroup_uniform_texture(grp, "matcaps", e_data.matcap_array);
507         DRW_shgroup_uniform_mat4(grp, "WinMatrix", (float *)e_data.winmat);
508         DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)e_data.viewvecs, 3);
509         DRW_shgroup_uniform_vec4(grp, "ssao_params", e_data.ssao_params, 1);
510         DRW_shgroup_uniform_vec3(grp, "matcaps_color[0]", (float *)e_data.matcap_colors, 24);
511
512         DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1);
513
514         DRW_shgroup_uniform_texture(grp, "ssao_jitter", sldata->jitter_tx);
515         DRW_shgroup_uniform_block(grp, "samples_block", sldata->sampling_ubo);
516         DRW_shgroup_uniform_block(grp, "material_block", stl->mat_ubo);
517
518         return grp;
519 }
520
521 static DRWShadingGroup *CLAY_hair_shgroup_create(CLAY_Data *vedata, DRWPass *pass, int *material_id)
522 {
523         CLAY_StorageList *stl = vedata->stl;
524         DRWShadingGroup *grp = DRW_shgroup_create(e_data.hair_sh, pass);
525
526         DRW_shgroup_uniform_texture(grp, "matcaps", e_data.matcap_array);
527         DRW_shgroup_uniform_int(grp, "mat_id", material_id, 1);
528         DRW_shgroup_uniform_block(grp, "material_block", stl->mat_ubo);
529
530         return grp;
531 }
532
533 static int search_mat_to_ubo(CLAY_Storage *storage, const CLAY_UBO_Material *mat_ubo_test)
534 {
535         /* For now just use a linear search and test all parameters */
536         /* TODO make a hash table */
537         for (int i = 0; i < storage->ubo_current_id; ++i) {
538                 CLAY_UBO_Material *ubo = &storage->mat_storage.materials[i];
539                 if (memcmp(ubo, mat_ubo_test, sizeof(*mat_ubo_test)) == 0) {
540                         return i;
541                 }
542         }
543
544         return -1;
545 }
546
547 static int search_hair_mat_to_ubo(CLAY_Storage *storage, const CLAY_HAIR_UBO_Material *hair_mat_ubo_test)
548 {
549         /* For now just use a linear search and test all parameters */
550         /* TODO make a hash table */
551         for (int i = 0; i < storage->hair_ubo_current_id; ++i) {
552                 CLAY_HAIR_UBO_Material *ubo = &storage->hair_mat_storage.materials[i];
553                 if (memcmp(ubo, hair_mat_ubo_test, sizeof(*hair_mat_ubo_test)) == 0) {
554                         return i;
555                 }
556         }
557
558         return -1;
559 }
560
561 static int push_mat_to_ubo(CLAY_Storage *storage, const CLAY_UBO_Material *mat_ubo_test)
562 {
563         int id = storage->ubo_current_id;
564         CLAY_UBO_Material *ubo = &storage->mat_storage.materials[id];
565
566         *ubo = *mat_ubo_test;
567
568         storage->ubo_current_id++;
569
570         return id;
571 }
572
573 static int push_hair_mat_to_ubo(CLAY_Storage *storage, const CLAY_HAIR_UBO_Material *hair_mat_ubo_test)
574 {
575         int id = storage->hair_ubo_current_id;
576         CLAY_HAIR_UBO_Material *ubo = &storage->hair_mat_storage.materials[id];
577
578         *ubo = *hair_mat_ubo_test;
579
580         storage->hair_ubo_current_id++;
581
582         return id;
583 }
584
585 static int mat_in_ubo(CLAY_Storage *storage, const CLAY_UBO_Material *mat_ubo_test)
586 {
587         /* Search material in UBO */
588         int id = search_mat_to_ubo(storage, mat_ubo_test);
589
590         /* if not found create it */
591         if (id == -1) {
592                 id = push_mat_to_ubo(storage, mat_ubo_test);
593         }
594
595         return id;
596 }
597
598 static int hair_mat_in_ubo(CLAY_Storage *storage, const CLAY_HAIR_UBO_Material *hair_mat_ubo_test)
599 {
600         /* Search material in UBO */
601         int id = search_hair_mat_to_ubo(storage, hair_mat_ubo_test);
602
603         /* if not found create it */
604         if (id == -1) {
605                 id = push_hair_mat_to_ubo(storage, hair_mat_ubo_test);
606         }
607
608         return id;
609 }
610
611 static void ubo_mat_from_object(Object *ob, CLAY_UBO_Material *r_ubo, bool *r_needs_ao)
612 {
613         IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_CLAY);
614
615         /* Default Settings */
616         float matcap_rot = BKE_collection_engine_property_value_get_float(props, "matcap_rotation");
617         float matcap_hue = BKE_collection_engine_property_value_get_float(props, "matcap_hue");
618         float matcap_sat = BKE_collection_engine_property_value_get_float(props, "matcap_saturation");
619         float matcap_val = BKE_collection_engine_property_value_get_float(props, "matcap_value");
620         float ssao_distance = BKE_collection_engine_property_value_get_float(props, "ssao_distance");
621         float ssao_factor_cavity = BKE_collection_engine_property_value_get_float(props, "ssao_factor_cavity");
622         float ssao_factor_edge = BKE_collection_engine_property_value_get_float(props, "ssao_factor_edge");
623         float ssao_attenuation = BKE_collection_engine_property_value_get_float(props, "ssao_attenuation");
624         int matcap_icon = BKE_collection_engine_property_value_get_int(props, "matcap_icon");
625
626         if (((ssao_factor_cavity > 0.0) || (ssao_factor_edge > 0.0)) &&
627             (ssao_distance > 0.0))
628         {
629                 *r_needs_ao = true;
630         }
631
632         memset(r_ubo, 0x0, sizeof(*r_ubo));
633
634         r_ubo->matcap_rot[0] = cosf(matcap_rot * 3.14159f * 2.0f);
635         r_ubo->matcap_rot[1] = sinf(matcap_rot * 3.14159f * 2.0f);
636
637         r_ubo->matcap_hsv[0] = matcap_hue + 0.5f;
638         r_ubo->matcap_hsv[1] = matcap_sat * 2.0f;
639         r_ubo->matcap_hsv[2] = matcap_val * 2.0f;
640
641         r_ubo->ssao_params_var[0] = ssao_distance;
642         r_ubo->ssao_params_var[1] = ssao_factor_cavity;
643         r_ubo->ssao_params_var[2] = ssao_factor_edge;
644         r_ubo->ssao_params_var[3] = ssao_attenuation;
645         r_ubo->matcap_id = matcap_to_index(matcap_icon);
646 }
647
648 static void hair_ubo_mat_from_object(Object *ob,  CLAY_HAIR_UBO_Material *r_ubo)
649 {
650         IDProperty *props = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_CLAY);
651
652         /* Default Settings */
653         float matcap_rot = BKE_collection_engine_property_value_get_float(props, "matcap_rotation");
654         float matcap_hue = BKE_collection_engine_property_value_get_float(props, "matcap_hue");
655         float matcap_sat = BKE_collection_engine_property_value_get_float(props, "matcap_saturation");
656         float matcap_val = BKE_collection_engine_property_value_get_float(props, "matcap_value");
657         float hair_randomness = BKE_collection_engine_property_value_get_float(props, "hair_brightness_randomness");
658         int matcap_icon = BKE_collection_engine_property_value_get_int(props, "matcap_icon");
659
660         memset(r_ubo, 0x0, sizeof(*r_ubo));
661
662         r_ubo->matcap_rot[0] = cosf(matcap_rot * 3.14159f * 2.0f);
663         r_ubo->matcap_rot[1] = sinf(matcap_rot * 3.14159f * 2.0f);
664         r_ubo->matcap_hsv[0] = matcap_hue + 0.5f;
665         r_ubo->matcap_hsv[1] = matcap_sat * 2.0f;
666         r_ubo->matcap_hsv[2] = matcap_val * 2.0f;
667         r_ubo->hair_randomness = hair_randomness;
668         r_ubo->matcap_id = matcap_to_index(matcap_icon);
669 }
670
671 static DRWShadingGroup *CLAY_object_shgrp_get(
672         CLAY_Data *vedata, Object *ob, CLAY_StorageList *stl, CLAY_PassList *psl, bool use_flat)
673 {
674         DRWShadingGroup **shgrps = use_flat ? stl->storage->shgrps_flat : stl->storage->shgrps;
675         CLAY_UBO_Material mat_ubo_test;
676
677         ubo_mat_from_object(ob, &mat_ubo_test, &stl->g_data->enable_ao);
678
679         int id = mat_in_ubo(stl->storage, &mat_ubo_test);
680
681         if (shgrps[id] == NULL) {
682                 shgrps[id] = CLAY_shgroup_create(
683                         vedata, use_flat ? psl->clay_pass_flat : psl->clay_pass, &e_data.ubo_mat_idxs[id], use_flat);
684         }
685
686         return shgrps[id];
687 }
688
689 static DRWShadingGroup *CLAY_hair_shgrp_get(CLAY_Data *vedata, Object *ob, CLAY_StorageList *stl, CLAY_PassList *psl)
690 {
691         DRWShadingGroup **hair_shgrps = stl->storage->hair_shgrps;
692
693         CLAY_HAIR_UBO_Material hair_mat_ubo_test;
694         hair_ubo_mat_from_object(ob, &hair_mat_ubo_test);
695
696         int hair_id = hair_mat_in_ubo(stl->storage, &hair_mat_ubo_test);
697
698         if (hair_shgrps[hair_id] == NULL) {
699                 hair_shgrps[hair_id] = CLAY_hair_shgroup_create(vedata, psl->hair_pass, &e_data.ubo_mat_idxs[hair_id]);
700         }
701
702         return hair_shgrps[hair_id];
703 }
704
705 static DRWShadingGroup *CLAY_object_shgrp_default_mode_get(
706         CLAY_Data *vedata, Object *ob, CLAY_StorageList *stl, CLAY_PassList *psl)
707 {
708         bool use_flat = DRW_object_is_flat_normal(ob);
709         return CLAY_object_shgrp_get(vedata, ob, stl, psl, use_flat);
710 }
711
712 static void clay_cache_init(void *vedata)
713 {
714         CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
715         CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
716
717         if (!stl->g_data) {
718                 /* Alloc transient pointers */
719                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
720         }
721
722         /* Disable AO unless a material needs it. */
723         stl->g_data->enable_ao = false;
724
725         /* Depth Pass */
726         {
727                 psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
728                 stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass);
729
730                 psl->depth_pass_cull = DRW_pass_create(
731                         "Depth Pass Cull",
732                         DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
733                 stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull);
734         }
735
736         /* Clay Pass */
737         {
738                 psl->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
739                 stl->storage->ubo_current_id = 0;
740                 memset(stl->storage->shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
741         }
742
743         /* Clay Pass (Flat) */
744         {
745                 psl->clay_pass_flat = DRW_pass_create("Clay Pass Flat", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
746                 memset(stl->storage->shgrps_flat, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
747         }
748
749         /* Hair Pass */
750         {
751                 psl->hair_pass = DRW_pass_create(
752                                      "Hair Pass",
753                                      DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE);
754                 stl->storage->hair_ubo_current_id = 0;
755                 memset(stl->storage->hair_shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
756         }
757 }
758
759 static void clay_cache_populate_particles(void *vedata, Object *ob)
760 {
761         CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
762         CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
763         const DRWContextState *draw_ctx = DRW_context_state_get();
764
765
766         Scene *scene = draw_ctx->scene;
767         Object *obedit = scene->obedit;
768
769         if (ob != obedit) {
770                 for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
771                         if (psys_check_enabled(ob, psys, false)) {
772                                 ParticleSettings *part = psys->part;
773                                 int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
774
775                                 if (draw_as == PART_DRAW_PATH && !psys->pathcache && !psys->childcache) {
776                                         draw_as = PART_DRAW_DOT;
777                                 }
778
779                                 static float mat[4][4];
780                                 unit_m4(mat);
781
782                                 if (draw_as == PART_DRAW_PATH) {
783                                         struct Gwn_Batch *geom = DRW_cache_particles_get_hair(psys, NULL);
784                                         DRWShadingGroup *hair_shgrp = CLAY_hair_shgrp_get(vedata, ob, stl, psl);
785                                         DRW_shgroup_call_add(hair_shgrp, geom, mat);
786                                 }
787                         }
788                 }
789         }
790 }
791
792 static void clay_cache_populate(void *vedata, Object *ob)
793 {
794         CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
795         CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
796
797         DRWShadingGroup *clay_shgrp;
798
799         if (!DRW_object_is_renderable(ob))
800                 return;
801
802         const DRWContextState *draw_ctx = DRW_context_state_get();
803         const bool is_active = (ob == draw_ctx->obact);
804         if (is_active) {
805                 if (DRW_object_is_mode_shade(ob) == true) {
806                         return;
807                 }
808         }
809
810         /* Handle particles first in case the emitter itself shouldn't be rendered. */
811         if (ob->type == OB_MESH) {
812                 clay_cache_populate_particles(vedata, ob);
813         }
814
815         if (DRW_check_object_visible_within_active_context(ob) == false) {
816                 return;
817         }
818
819         struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
820         if (geom) {
821                 IDProperty *ces_mode_ob = BKE_layer_collection_engine_evaluated_get(ob, COLLECTION_MODE_OBJECT, "");
822                 const bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
823                 const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
824                 const bool is_default_mode_shader = is_sculpt_mode;
825
826                 /* Depth Prepass */
827                 {
828                         DRWShadingGroup *depth_shgrp = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
829                         if (is_sculpt_mode) {
830                                 DRW_shgroup_call_sculpt_add(depth_shgrp, ob, ob->obmat);
831                         }
832                         else {
833                                 DRW_shgroup_call_object_add(depth_shgrp, geom, ob);
834                         }
835                 }
836
837                 /* Shading */
838                 if (is_default_mode_shader) {
839                         clay_shgrp = CLAY_object_shgrp_default_mode_get(vedata, ob, stl, psl);
840                 }
841                 else {
842                         clay_shgrp = CLAY_object_shgrp_get(vedata, ob, stl, psl, false);
843                 }
844
845                 if (is_sculpt_mode) {
846                         DRW_shgroup_call_sculpt_add(clay_shgrp, ob, ob->obmat);
847                 }
848                 else {
849                         DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
850                 }
851         }
852 }
853
854 static void clay_cache_finish(void *vedata)
855 {
856         CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
857
858         DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage);
859         DRW_uniformbuffer_update(stl->hair_mat_ubo, &stl->storage->hair_mat_storage);
860 }
861
862 static void clay_draw_scene(void *vedata)
863 {
864         CLAY_StorageList *stl = ((CLAY_Data *)vedata)->stl;
865         CLAY_PassList *psl = ((CLAY_Data *)vedata)->psl;
866         CLAY_FramebufferList *fbl = ((CLAY_Data *)vedata)->fbl;
867         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
868
869         /* Pass 1 : Depth pre-pass */
870         if (stl->g_data->enable_ao) {
871                 DRW_draw_pass(psl->depth_pass);
872                 DRW_draw_pass(psl->depth_pass_cull);
873         }
874         else {
875                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
876                 DRW_pass_state_set(psl->clay_pass, state);
877                 DRW_pass_state_set(psl->clay_pass_flat, state);
878         }
879
880         /* Pass 2 : Duplicate depth */
881         /* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */
882         if (DRW_state_is_fbo() && stl->g_data->enable_ao) {
883                 /* attach temp textures */
884                 DRW_framebuffer_texture_attach(fbl->dupli_depth, e_data.depth_dup, 0, 0);
885
886                 DRW_framebuffer_blit(dfbl->default_fb, fbl->dupli_depth, true, false);
887
888                 /* detach temp textures */
889                 DRW_framebuffer_texture_detach(e_data.depth_dup);
890
891                 /* restore default fb */
892                 DRW_framebuffer_bind(dfbl->default_fb);
893         }
894
895         /* Pass 3 : Shading */
896         DRW_draw_pass(psl->clay_pass);
897         DRW_draw_pass(psl->clay_pass_flat);
898         DRW_draw_pass(psl->hair_pass);
899 }
900
901 static void clay_layer_collection_settings_create(RenderEngine *UNUSED(engine), IDProperty *props)
902 {
903         BLI_assert(props &&
904                    props->type == IDP_GROUP &&
905                    props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
906
907         BKE_collection_engine_property_add_int(props, "matcap_icon", ICON_MATCAP_01);
908         BKE_collection_engine_property_add_int(props, "type", CLAY_MATCAP_NONE);
909         BKE_collection_engine_property_add_float(props, "matcap_rotation", 0.0f);
910         BKE_collection_engine_property_add_float(props, "matcap_hue", 0.5f);
911         BKE_collection_engine_property_add_float(props, "matcap_saturation", 0.5f);
912         BKE_collection_engine_property_add_float(props, "matcap_value", 0.5f);
913         BKE_collection_engine_property_add_float(props, "ssao_distance", 0.2f);
914         BKE_collection_engine_property_add_float(props, "ssao_attenuation", 1.0f);
915         BKE_collection_engine_property_add_float(props, "ssao_factor_cavity", 1.0f);
916         BKE_collection_engine_property_add_float(props, "ssao_factor_edge", 1.0f);
917         BKE_collection_engine_property_add_float(props, "hair_brightness_randomness", 0.0f);
918 }
919
920 static void clay_view_layer_settings_create(RenderEngine *UNUSED(engine), IDProperty *props)
921 {
922         BLI_assert(props &&
923                    props->type == IDP_GROUP &&
924                    props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
925
926         BKE_collection_engine_property_add_int(props, "ssao_samples", 16);
927 }
928
929 static void clay_engine_free(void)
930 {
931         DRW_SHADER_FREE_SAFE(e_data.clay_sh);
932         DRW_SHADER_FREE_SAFE(e_data.clay_flat_sh);
933         DRW_SHADER_FREE_SAFE(e_data.hair_sh);
934         DRW_TEXTURE_FREE_SAFE(e_data.matcap_array);
935 }
936
937 static const DrawEngineDataSize clay_data_size = DRW_VIEWPORT_DATA_SIZE(CLAY_Data);
938
939 DrawEngineType draw_engine_clay_type = {
940         NULL, NULL,
941         N_("Clay"),
942         &clay_data_size,
943         &clay_engine_init,
944         &clay_engine_free,
945         &clay_cache_init,
946         &clay_cache_populate,
947         &clay_cache_finish,
948         NULL,
949         &clay_draw_scene,
950         NULL,
951         NULL,
952         NULL,
953 };
954
955 RenderEngineType DRW_engine_viewport_clay_type = {
956         NULL, NULL,
957         CLAY_ENGINE, N_("Clay"), RE_INTERNAL,
958         NULL, NULL, NULL, NULL, NULL, NULL, NULL,
959         &clay_layer_collection_settings_create,
960         &clay_view_layer_settings_create,
961         &draw_engine_clay_type,
962         {NULL, NULL, NULL}
963 };
964
965
966 #undef CLAY_ENGINE
967
968 #endif  /* WITH_CLAY_ENGINE */