Eevee: Add Variance Shadow Mapping
[blender.git] / source / blender / draw / engines / eevee / eevee_lights.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 eevee_lights.c
23  *  \ingroup DNA
24  */
25
26 #include "DRW_render.h"
27
28 #include "BKE_object.h"
29
30 #include "eevee_engine.h"
31 #include "eevee_private.h"
32
33 /* Theses are the structs stored inside Objects.
34  * It works with even if the object is in multiple layers
35  * because we don't get the same "Object *" for each layer. */
36 typedef struct EEVEE_LightData {
37         short light_id, shadow_id;
38 } EEVEE_LightData;
39
40 typedef struct EEVEE_ShadowCubeData {
41         short light_id, shadow_id;
42         float viewprojmat[6][4][4];
43 } EEVEE_ShadowCubeData;
44
45 typedef struct EEVEE_ShadowCascadeData {
46         short light_id, shadow_id;
47         float viewprojmat[MAX_CASCADE_NUM][4][4]; /* World->Lamp->NDC : used for rendering the shadow map. */
48 } EEVEE_ShadowCascadeData;
49
50 typedef struct ShadowCaster {
51         struct ShadowCaster *next, *prev;
52         void *ob;
53         bool prune;
54 } ShadowCaster;
55
56 static struct {
57         struct GPUShader *shadow_sh;
58         struct GPUShader *shadow_store_cube_sh[SHADOW_METHOD_MAX];
59         struct GPUShader *shadow_store_cascade_sh[SHADOW_METHOD_MAX];
60 } e_data = {NULL}; /* Engine data */
61
62 extern char datatoc_shadow_vert_glsl[];
63 extern char datatoc_shadow_geom_glsl[];
64 extern char datatoc_shadow_frag_glsl[];
65 extern char datatoc_shadow_store_frag_glsl[];
66
67 /* *********** FUNCTIONS *********** */
68
69 void EEVEE_lights_init(EEVEE_SceneLayerData *sldata)
70 {
71         const unsigned int shadow_ubo_size = sizeof(EEVEE_ShadowCube) * MAX_SHADOW_CUBE +
72                                              sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE;
73
74         const DRWContextState *draw_ctx = DRW_context_state_get();
75         SceneLayer *scene_layer = draw_ctx->scene_layer;
76         IDProperty *props = BKE_scene_layer_engine_evaluated_get(scene_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
77
78         if (!e_data.shadow_sh) {
79                 e_data.shadow_sh = DRW_shader_create(
80                         datatoc_shadow_vert_glsl, datatoc_shadow_geom_glsl, datatoc_shadow_frag_glsl, NULL);
81
82                 e_data.shadow_store_cube_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define ESM\n");
83                 e_data.shadow_store_cascade_sh[SHADOW_ESM] = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define ESM\n"
84                                                                                                                           "#define CSM\n");
85
86                 e_data.shadow_store_cube_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define VSM\n");
87                 e_data.shadow_store_cascade_sh[SHADOW_VSM] = DRW_shader_create_fullscreen(datatoc_shadow_store_frag_glsl, "#define VSM\n"
88                                                                                                                           "#define CSM\n");
89         }
90
91         if (!sldata->lamps) {
92                 sldata->lamps              = MEM_callocN(sizeof(EEVEE_LampsInfo), "EEVEE_LampsInfo");
93                 sldata->light_ubo          = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
94                 sldata->shadow_ubo         = DRW_uniformbuffer_create(shadow_ubo_size, NULL);
95                 sldata->shadow_render_ubo  = DRW_uniformbuffer_create(sizeof(EEVEE_ShadowRender), NULL);
96         }
97
98         int sh_method = BKE_collection_engine_property_value_get_int(props, "shadow_method");
99         int sh_size = BKE_collection_engine_property_value_get_int(props, "shadow_size");
100
101         EEVEE_LampsInfo *linfo = sldata->lamps;
102         if ((linfo->shadow_size != sh_size) || (linfo->shadow_method != sh_method)) {
103                 BLI_assert((sh_size > 0) && (sh_size <= 8192));
104                 DRW_TEXTURE_FREE_SAFE(sldata->shadow_pool);
105                 DRW_TEXTURE_FREE_SAFE(sldata->shadow_cascade_target);
106
107                 linfo->shadow_method = sh_method;
108                 linfo->shadow_size = sh_size;
109                 linfo->shadow_render_data.stored_texel_size = 1.0 / (float)linfo->shadow_size;
110
111                 /* Compute adequate size for the cubemap render target.
112                  * The 3.0f factor is here to make sure there is no under sampling between
113                  * the octahedron mapping and the cubemap. */
114                 int new_cube_target_size = (int)ceil(sqrt((float)(sh_size * sh_size) / 6.0f) * 3.0f);
115
116                 CLAMP(new_cube_target_size, 1, 4096);
117
118                 if (linfo->shadow_cube_target_size != new_cube_target_size) {
119                         linfo->shadow_cube_target_size = new_cube_target_size;
120                         DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_target);
121                         linfo->shadow_render_data.cube_texel_size = 1.0 / (float)linfo->shadow_cube_target_size;
122                 }
123         }
124 }
125
126 void EEVEE_lights_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
127 {
128         EEVEE_LampsInfo *linfo = sldata->lamps;
129
130         linfo->num_light = linfo->num_cube = linfo->num_cascade = linfo->num_shadow = 0;
131         memset(linfo->light_ref, 0, sizeof(linfo->light_ref));
132         memset(linfo->shadow_cube_ref, 0, sizeof(linfo->shadow_cube_ref));
133         memset(linfo->shadow_cascade_ref, 0, sizeof(linfo->shadow_cascade_ref));
134
135         {
136                 psl->shadow_cube_store_pass = DRW_pass_create("Shadow Storage Pass", DRW_STATE_WRITE_COLOR);
137
138                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_cube_sh[linfo->shadow_method], psl->shadow_cube_store_pass);
139                 DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_cube_target);
140                 DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
141                 DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
142         }
143
144         {
145                 psl->shadow_cascade_store_pass = DRW_pass_create("Shadow Cascade Storage Pass", DRW_STATE_WRITE_COLOR);
146
147                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_store_cascade_sh[linfo->shadow_method], psl->shadow_cascade_store_pass);
148                 DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_cascade_target);
149                 DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
150                 DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
151         }
152
153         {
154                 psl->shadow_cube_pass = DRW_pass_create("Shadow Cube Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
155         }
156
157         {
158                 psl->shadow_cascade_pass = DRW_pass_create("Shadow Cascade Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
159         }
160
161         /* Reset shadow casters list */
162         BLI_freelistN(&sldata->shadow_casters);
163 }
164
165 void EEVEE_lights_cache_add(EEVEE_SceneLayerData *sldata, Object *ob)
166 {
167         EEVEE_LampsInfo *linfo = sldata->lamps;
168
169         /* Step 1 find all lamps in the scene and setup them */
170         if (linfo->num_light > MAX_LIGHT) {
171                 printf("Too much lamps in the scene !!!\n");
172                 linfo->num_light = MAX_LIGHT;
173         }
174         else {
175                 Lamp *la = (Lamp *)ob->data;
176                 EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
177
178                 if ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0) {
179                         led->need_update = true;
180                 }
181
182                 MEM_SAFE_FREE(led->storage);
183
184 #if 1 /* TODO Waiting for notified refresh. only on scene change. Else too much perf cost. */
185                 if (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY)) {
186                         if (la->type == LA_SUN && linfo->num_cascade < MAX_SHADOW_CASCADE) {
187                                 led->storage = MEM_mallocN(sizeof(EEVEE_ShadowCascadeData), "EEVEE_ShadowCascadeData");
188                                 ((EEVEE_ShadowCascadeData *)led->storage)->shadow_id = linfo->num_shadow;
189                                 linfo->shadow_cascade_ref[linfo->num_cascade] = ob;
190                                 linfo->num_cascade++;
191                                 linfo->num_shadow += MAX_CASCADE_NUM;
192                         }
193                         else if ((la->type == LA_SPOT || la->type == LA_LOCAL || la->type == LA_AREA)
194                                   && linfo->num_cube < MAX_SHADOW_CUBE) {
195                                 led->storage = MEM_mallocN(sizeof(EEVEE_ShadowCubeData), "EEVEE_ShadowCubeData");
196                                 ((EEVEE_ShadowCubeData *)led->storage)->shadow_id = linfo->num_shadow;
197                                 linfo->shadow_cube_ref[linfo->num_cube] = ob;
198                                 linfo->num_cube++;
199                                 linfo->num_shadow += 1;
200                         }
201
202                 }
203 #else
204                 UNUSED_VARS(la);
205 #endif
206                 /* Default light without shadows */
207                 if (!led->storage) {
208                         led->storage = MEM_mallocN(sizeof(EEVEE_LightData), "EEVEE_LightData");
209                         ((EEVEE_LightData *)led->storage)->shadow_id = -1;
210                 }
211
212                 ((EEVEE_LightData *)led->storage)->light_id = linfo->num_light;
213                 linfo->light_ref[linfo->num_light] = ob;
214                 linfo->num_light++;
215         }
216 }
217
218 /* Add a shadow caster to the shadowpasses */
219 void EEVEE_lights_cache_shcaster_add(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, struct Gwn_Batch *geom, float (*obmat)[4])
220 {
221         DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cube_pass, geom);
222         DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
223         DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
224
225         for (int i = 0; i < 6; ++i)
226                 DRW_shgroup_call_dynamic_add_empty(grp);
227
228         grp = DRW_shgroup_instance_create(e_data.shadow_sh, psl->shadow_cascade_pass, geom);
229         DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
230         DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
231
232         for (int i = 0; i < MAX_CASCADE_NUM; ++i)
233                 DRW_shgroup_call_dynamic_add_empty(grp);
234 }
235
236 void EEVEE_lights_cache_shcaster_material_add(
237         EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, struct GPUMaterial *gpumat, struct Gwn_Batch *geom, float (*obmat)[4], float *alpha_threshold)
238 {
239         DRWShadingGroup *grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cube_pass, geom);
240
241         if (grp == NULL) return;
242
243         DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
244         DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
245
246         if (alpha_threshold != NULL)
247                 DRW_shgroup_uniform_float(grp, "alphaThreshold", alpha_threshold, 1);
248
249         for (int i = 0; i < 6; ++i)
250                 DRW_shgroup_call_dynamic_add_empty(grp);
251
252         grp = DRW_shgroup_material_instance_create(gpumat, psl->shadow_cascade_pass, geom);
253         DRW_shgroup_uniform_block(grp, "shadow_render_block", sldata->shadow_render_ubo);
254         DRW_shgroup_uniform_mat4(grp, "ShadowModelMatrix", (float *)obmat);
255
256         if (alpha_threshold != NULL)
257                 DRW_shgroup_uniform_float(grp, "alphaThreshold", alpha_threshold, 1);
258
259         for (int i = 0; i < MAX_CASCADE_NUM; ++i)
260                 DRW_shgroup_call_dynamic_add_empty(grp);
261 }
262
263 void EEVEE_lights_cache_finish(EEVEE_SceneLayerData *sldata)
264 {
265         EEVEE_LampsInfo *linfo = sldata->lamps;
266         DRWTextureFormat shadow_pool_format;
267
268         /* Setup enough layers. */
269         /* Free textures if number mismatch. */
270         if ((linfo->num_shadow != linfo->cache_num_shadow) ||
271                 (linfo->num_cube != linfo->cache_num_cube) ||
272             (linfo->num_cascade != linfo->cache_num_cascade))
273         {
274                 DRW_TEXTURE_FREE_SAFE(sldata->shadow_pool);
275                 linfo->cache_num_cube = linfo->num_cube;
276                 linfo->cache_num_cascade = linfo->num_cascade;
277                 linfo->cache_num_shadow = linfo->num_shadow;
278                 linfo->update_flag |= LIGHT_UPDATE_SHADOW_CUBE;
279         }
280
281         switch (linfo->shadow_method) {
282                 case SHADOW_ESM: shadow_pool_format = DRW_TEX_R_32; break;
283                 case SHADOW_VSM: shadow_pool_format = DRW_TEX_RG_32; break;
284                 default:
285                         BLI_assert(!"Incorrect Shadow Method");
286                         break;
287         }
288
289         if (!sldata->shadow_cube_target) {
290                 /* TODO render everything on the same 2d render target using clip planes and no Geom Shader. */
291                 /* Cubemaps */
292                 sldata->shadow_cube_target = DRW_texture_create_cube(linfo->shadow_cube_target_size, DRW_TEX_DEPTH_24, 0, NULL);
293         }
294
295         if (!sldata->shadow_cascade_target) {
296                 /* CSM */
297                 sldata->shadow_cascade_target = DRW_texture_create_2D_array(
298                         linfo->shadow_size, linfo->shadow_size, MAX_CASCADE_NUM, DRW_TEX_DEPTH_24, 0, NULL);
299         }
300
301         /* Initialize Textures Array first so DRW_framebuffer_init just bind them. */
302         if (!sldata->shadow_pool) {
303                 /* All shadows fit in this array */
304                 sldata->shadow_pool = DRW_texture_create_2D_array(
305                         linfo->shadow_size, linfo->shadow_size, max_ff(1, linfo->num_cube + linfo->num_cascade),
306                         shadow_pool_format, DRW_TEX_FILTER, NULL);
307         }
308
309         /* Render FB */
310         DRWFboTexture tex_cascade = {&sldata->shadow_cube_target, DRW_TEX_DEPTH_24, 0};
311         DRW_framebuffer_init(&sldata->shadow_target_fb, &draw_engine_eevee_type,
312                              linfo->shadow_size, linfo->shadow_size,
313                              &tex_cascade, 1);
314
315         /* Storage FB */
316         DRWFboTexture tex_pool = {&sldata->shadow_pool, shadow_pool_format, DRW_TEX_FILTER};
317         DRW_framebuffer_init(&sldata->shadow_store_fb, &draw_engine_eevee_type,
318                              linfo->shadow_size, linfo->shadow_size,
319                              &tex_pool, 1);
320
321         /* Restore */
322         DRW_framebuffer_texture_detach(sldata->shadow_cube_target);
323
324         /* Update Lamps UBOs. */
325         EEVEE_lights_update(sldata);
326 }
327
328 /* Update buffer with lamp data */
329 static void eevee_light_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
330 {
331         /* TODO only update if data changes */
332         EEVEE_LightData *evld = led->storage;
333         EEVEE_Light *evli = linfo->light_data + evld->light_id;
334         Lamp *la = (Lamp *)ob->data;
335         float mat[4][4], scale[3], power;
336
337         /* Position */
338         copy_v3_v3(evli->position, ob->obmat[3]);
339
340         /* Color */
341         copy_v3_v3(evli->color, &la->r);
342
343         /* Influence Radius */
344         evli->dist = la->dist;
345
346         /* Vectors */
347         normalize_m4_m4_ex(mat, ob->obmat, scale);
348         copy_v3_v3(evli->forwardvec, mat[2]);
349         normalize_v3(evli->forwardvec);
350         negate_v3(evli->forwardvec);
351
352         copy_v3_v3(evli->rightvec, mat[0]);
353         normalize_v3(evli->rightvec);
354
355         copy_v3_v3(evli->upvec, mat[1]);
356         normalize_v3(evli->upvec);
357
358         /* Spot size & blend */
359         if (la->type == LA_SPOT) {
360                 evli->sizex = scale[0] / scale[2];
361                 evli->sizey = scale[1] / scale[2];
362                 evli->spotsize = cosf(la->spotsize * 0.5f);
363                 evli->spotblend = (1.0f - evli->spotsize) * la->spotblend;
364                 evli->radius = max_ff(0.001f, la->area_size);
365         }
366         else if (la->type == LA_AREA) {
367                 evli->sizex = max_ff(0.0001f, la->area_size * scale[0] * 0.5f);
368                 if (la->area_shape == LA_AREA_RECT) {
369                         evli->sizey = max_ff(0.0001f, la->area_sizey * scale[1] * 0.5f);
370                 }
371                 else {
372                         evli->sizey = max_ff(0.0001f, la->area_size * scale[1] * 0.5f);
373                 }
374         }
375         else {
376                 evli->radius = max_ff(0.001f, la->area_size);
377         }
378
379         /* Make illumination power constant */
380         if (la->type == LA_AREA) {
381                 power = 1.0f / (evli->sizex * evli->sizey * 4.0f * M_PI) /* 1/(w*h*Pi) */
382                         * 80.0f; /* XXX : Empirical, Fit cycles power */
383         }
384         else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
385                 power = 1.0f / (4.0f * evli->radius * evli->radius * M_PI * M_PI) /* 1/(4*r²*Pi²) */
386                         * M_PI * M_PI * M_PI * 10.0; /* XXX : Empirical, Fit cycles power */
387
388                 /* for point lights (a.k.a radius == 0.0) */
389                 // power = M_PI * M_PI * 0.78; /* XXX : Empirical, Fit cycles power */
390         }
391         else {
392                 power = 1.0f;
393         }
394         mul_v3_fl(evli->color, power * la->energy);
395
396         /* Lamp Type */
397         evli->lamptype = (float)la->type;
398
399         /* No shadow by default */
400         evli->shadowid = -1.0f;
401 }
402
403 static void eevee_shadow_cube_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
404 {
405         float projmat[4][4];
406
407         EEVEE_ShadowCubeData *evsmp = (EEVEE_ShadowCubeData *)led->storage;
408         EEVEE_Light *evli = linfo->light_data + evsmp->light_id;
409         EEVEE_ShadowCube *evsh = linfo->shadow_cube_data + evsmp->shadow_id;
410         Lamp *la = (Lamp *)ob->data;
411
412         perspective_m4(projmat, -la->clipsta, la->clipsta, -la->clipsta, la->clipsta, la->clipsta, la->clipend);
413
414         for (int i = 0; i < 6; ++i) {
415                 float tmp[4][4];
416                 unit_m4(tmp);
417                 negate_v3_v3(tmp[3], ob->obmat[3]);
418                 mul_m4_m4m4(tmp, cubefacemat[i], tmp);
419                 mul_m4_m4m4(evsmp->viewprojmat[i], projmat, tmp);
420         }
421
422         evsh->bias = 0.05f * la->bias;
423         evsh->near = la->clipsta;
424         evsh->far = la->clipend;
425         evsh->exp = (linfo->shadow_method == SHADOW_VSM) ? la->bleedbias : la->bleedexp;
426
427         evli->shadowid = (float)(evsmp->shadow_id);
428 }
429
430 #define LERP(t, a, b) ((a) + (t) * ((b) - (a)))
431
432 static void frustum_min_bounding_sphere(const float corners[8][4], float r_center[3], float *r_radius)
433 {
434 #if 0 /* Simple solution but waist too much space. */
435         float minvec[3], maxvec[3];
436
437         /* compute the bounding box */
438         INIT_MINMAX(minvec, maxvec);
439         for (int i = 0; i < 8; ++i)     {
440                 minmax_v3v3_v3(minvec, maxvec, corners[i]);
441         }
442
443         /* compute the bounding sphere of this box */
444         r_radius = len_v3v3(minvec, maxvec) * 0.5f;
445         add_v3_v3v3(r_center, minvec, maxvec);
446         mul_v3_fl(r_center, 0.5f);
447 #else
448         /* Make the bouding sphere always centered on the front diagonal */
449         add_v3_v3v3(r_center, corners[4], corners[7]);
450         mul_v3_fl(r_center, 0.5f);
451         *r_radius = len_v3v3(corners[0], r_center);
452
453         /* Search the largest distance between the sphere center
454          * and the front plane corners. */
455         for (int i = 0; i < 4; ++i) {
456                 float rad = len_v3v3(corners[4+i], r_center);
457                 if (rad > *r_radius) {
458                         *r_radius = rad;
459                 }
460         }
461 #endif
462 }
463
464 static void eevee_shadow_cascade_setup(Object *ob, EEVEE_LampsInfo *linfo, EEVEE_LampEngineData *led)
465 {
466         /* Camera Matrices */
467         float persmat[4][4], persinv[4][4];
468         float viewprojmat[4][4], projinv[4][4];
469         float near, far;
470         float near_v[4] = {0.0f, 0.0f, -1.0f, 1.0f};
471         float far_v[4] = {0.0f, 0.0f,  1.0f, 1.0f};
472         bool is_persp = DRW_viewport_is_persp_get();
473         DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
474         invert_m4_m4(persinv, persmat);
475         /* FIXME : Get near / far from Draw manager? */
476         DRW_viewport_matrix_get(viewprojmat, DRW_MAT_WIN);
477         invert_m4_m4(projinv, viewprojmat);
478         mul_m4_v4(projinv, near_v);
479         mul_m4_v4(projinv, far_v);
480         near = near_v[2];
481         far = far_v[2]; /* TODO: Should be a shadow parameter */
482         if (is_persp) {
483                 near /= near_v[3];
484                 far /= far_v[3];
485         }
486
487         /* Lamps Matrices */
488         float viewmat[4][4], projmat[4][4];
489         int cascade_ct = MAX_CASCADE_NUM;
490         float shadow_res = 512.0f; /* TODO parameter */
491
492         EEVEE_ShadowCascadeData *evscp = (EEVEE_ShadowCascadeData *)led->storage;
493         EEVEE_Light *evli = linfo->light_data + evscp->light_id;
494         EEVEE_ShadowCascade *evsh = linfo->shadow_cascade_data + evscp->shadow_id;
495         Lamp *la = (Lamp *)ob->data;
496
497         /* The technique consists into splitting
498          * the view frustum into several sub-frustum
499          * that are individually receiving one shadow map */
500
501         /* init near/far */
502         for (int c = 0; c < MAX_CASCADE_NUM; ++c) {
503                 evsh->split[c] = far;
504         }
505
506         /* Compute split planes */
507         float splits_ndc[MAX_CASCADE_NUM + 1];
508         splits_ndc[0] = -1.0f;
509         splits_ndc[cascade_ct] = 1.0f;
510         for (int c = 1; c < cascade_ct; ++c) {
511                 const float lambda = 0.8f; /* TODO : Parameter */
512
513                 /* View Space */
514                 float linear_split = LERP(((float)(c) / (float)cascade_ct), near, far);
515                 float exp_split = near * powf(far / near, (float)(c) / (float)cascade_ct);
516
517                 if (is_persp) {
518                         evsh->split[c-1] = LERP(lambda, linear_split, exp_split);
519                 }
520                 else {
521                         evsh->split[c-1] = linear_split;
522                 }
523
524                 /* NDC Space */
525                 float p[4] = {1.0f, 1.0f, evsh->split[c-1], 1.0f};
526                 mul_m4_v4(viewprojmat, p);
527                 splits_ndc[c] = p[2];
528
529                 if (is_persp) {
530                         splits_ndc[c] /= p[3];
531                 }
532         }
533
534         /* For each cascade */
535         for (int c = 0; c < cascade_ct; ++c) {
536                 /* Given 8 frustrum corners */
537                 float corners[8][4] = {
538                         /* Near Cap */
539                         {-1.0f, -1.0f, splits_ndc[c], 1.0f},
540                         { 1.0f, -1.0f, splits_ndc[c], 1.0f},
541                         {-1.0f,  1.0f, splits_ndc[c], 1.0f},
542                         { 1.0f,  1.0f, splits_ndc[c], 1.0f},
543                         /* Far Cap */
544                         {-1.0f, -1.0f, splits_ndc[c+1], 1.0f},
545                         { 1.0f, -1.0f, splits_ndc[c+1], 1.0f},
546                         {-1.0f,  1.0f, splits_ndc[c+1], 1.0f},
547                         { 1.0f,  1.0f, splits_ndc[c+1], 1.0f}
548                 };
549
550                 /* Transform them into world space */
551                 for (int i = 0; i < 8; ++i)     {
552                         mul_m4_v4(persinv, corners[i]);
553                         mul_v3_fl(corners[i], 1.0f / corners[i][3]);
554                         corners[i][3] = 1.0f;
555                 }
556
557                 /* Project them into light space */
558                 invert_m4_m4(viewmat, ob->obmat);
559                 normalize_v3(viewmat[0]);
560                 normalize_v3(viewmat[1]);
561                 normalize_v3(viewmat[2]);
562
563                 for (int i = 0; i < 8; ++i)     {
564                         mul_m4_v4(viewmat, corners[i]);
565                 }
566
567                 float center[3], radius;
568                 frustum_min_bounding_sphere(corners, center, &radius);
569
570                 /* Snap projection center to nearest texel to cancel shimering. */
571                 float shadow_origin[2], shadow_texco[2];
572                 mul_v2_v2fl(shadow_origin, center, shadow_res / (2.0f * radius)); /* Light to texture space. */
573
574                 /* Find the nearest texel. */
575                 shadow_texco[0] = round(shadow_origin[0]);
576                 shadow_texco[1] = round(shadow_origin[1]);
577
578                 /* Compute offset. */
579                 sub_v2_v2(shadow_texco, shadow_origin);
580                 mul_v2_fl(shadow_texco, (2.0f * radius) / shadow_res); /* Texture to light space. */
581
582                 /* Apply offset. */
583                 add_v2_v2(center, shadow_texco);
584
585                 /* Expand the projection to cover frustum range */
586                 orthographic_m4(projmat,
587                                 center[0] - radius,
588                                 center[0] + radius,
589                                 center[1] - radius,
590                                 center[1] + radius,
591                                 la->clipsta, la->clipend);
592
593                 mul_m4_m4m4(evscp->viewprojmat[c], projmat, viewmat);
594                 mul_m4_m4m4(evsh->shadowmat[c], texcomat, evscp->viewprojmat[c]);
595
596                 /* TODO modify bias depending on the cascade radius */
597                 evsh->bias = 0.005f * la->bias;
598         }
599
600         evli->shadowid = (float)(MAX_SHADOW_CUBE + evscp->shadow_id);
601 }
602
603 /* Used for checking if object is inside the shadow volume. */
604 static bool cube_bbox_intersect(const float cube_center[3], float cube_half_dim, const BoundBox *bb, float (*obmat)[4])
605 {
606         float min[3], max[4], tmp[4][4];
607         unit_m4(tmp);
608         translate_m4(tmp, -cube_center[0], -cube_center[1], -cube_center[2]);
609         mul_m4_m4m4(tmp, tmp, obmat);
610
611         /* Just simple AABB intersection test in world space. */
612         INIT_MINMAX(min, max);
613         for (int i = 0; i < 8; ++i) {
614                 float vec[3];
615                 copy_v3_v3(vec, bb->vec[i]);
616                 mul_m4_v3(tmp, vec);
617                 minmax_v3v3_v3(min, max, vec);
618         }
619
620     if (MAX3(max[0], max[1], max[2]) < -cube_half_dim) return false;
621     if (MIN3(min[0], min[1], min[2]) >  cube_half_dim) return false;
622
623         return true;
624 }
625
626 static ShadowCaster *search_object_in_list(ListBase *list, Object *ob)
627 {
628         for (ShadowCaster *ldata = list->first; ldata; ldata = ldata->next) {
629                 if (ldata->ob == ob)
630                         return ldata;
631         }
632
633         return NULL;
634 }
635
636 static void delete_pruned_shadowcaster(EEVEE_LampEngineData *led)
637 {
638         ShadowCaster *next;
639         for (ShadowCaster *ldata = led->shadow_caster_list.first; ldata; ldata = next) {
640                 next = ldata->next;
641                 if (ldata->prune == true) {
642                         led->need_update = true;
643                         BLI_freelinkN(&led->shadow_caster_list, ldata);
644                 }
645         }
646 }
647
648 static void light_tag_shadow_update(Object *lamp, Object *ob)
649 {
650         Lamp *la = lamp->data;
651         EEVEE_LampEngineData *led = EEVEE_lamp_data_get(lamp);
652
653         bool is_inside_range = cube_bbox_intersect(lamp->obmat[3], la->clipend, BKE_object_boundbox_get(ob), ob->obmat);
654         ShadowCaster *ldata = search_object_in_list(&led->shadow_caster_list, ob);
655
656         if (is_inside_range) {
657                 if (ldata == NULL) {
658                         /* Object was not a shadow caster previously but is now. Add it. */
659                         ldata = MEM_callocN(sizeof(ShadowCaster), "ShadowCaster");
660                         ldata->ob = ob;
661                         BLI_addtail(&led->shadow_caster_list, ldata);
662                         led->need_update = true;
663                 }
664                 else {
665                         EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(ob);
666                         if (oedata->need_update) {
667                                 led->need_update = true;
668                         }
669                 }
670                 ldata->prune = false;
671         }
672         else if (ldata != NULL) {
673                 /* Object was a shadow caster previously and is not anymore. Remove it. */
674                 led->need_update = true;
675                 BLI_freelinkN(&led->shadow_caster_list, ldata);
676         }
677 }
678
679 static void eevee_lights_shcaster_updated(EEVEE_SceneLayerData *sldata, Object *ob)
680 {
681         Object *lamp;
682         EEVEE_LampsInfo *linfo = sldata->lamps;
683
684         /* Iterate over all shadow casting lamps to see if
685          * each of them needs update because of this object */
686         for (int i = 0; (lamp = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) {
687                 light_tag_shadow_update(lamp, ob);
688         }
689 }
690
691 void EEVEE_lights_update(EEVEE_SceneLayerData *sldata)
692 {
693         EEVEE_LampsInfo *linfo = sldata->lamps;
694         Object *ob;
695         int i;
696
697         /* Prune shadow casters to remove if object does not exists anymore (unprune them if object exists) */
698         Object *lamp;
699         for (i = 0; (lamp = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) {
700                 EEVEE_LampEngineData *led = EEVEE_lamp_data_get(lamp);
701
702                 if ((linfo->update_flag & LIGHT_UPDATE_SHADOW_CUBE) != 0) {
703                         led->need_update = true;
704                 }
705
706                 for (ShadowCaster *ldata = led->shadow_caster_list.first; ldata; ldata = ldata->next) {
707                         ldata->prune = true;
708                 }
709         }
710
711         for (LinkData *ldata = sldata->shadow_casters.first; ldata; ldata = ldata->next) {
712                 eevee_lights_shcaster_updated(sldata, ldata->data);
713         }
714
715         for (i = 0; (ob = linfo->light_ref[i]) && (i < MAX_LIGHT); i++) {
716                 EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
717                 eevee_light_setup(ob, linfo, led);
718         }
719
720         for (i = 0; (ob = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) {
721                 EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
722                 eevee_shadow_cube_setup(ob, linfo, led);
723                 delete_pruned_shadowcaster(led);
724         }
725
726         for (i = 0; (ob = linfo->shadow_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) {
727                 EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
728                 eevee_shadow_cascade_setup(ob, linfo, led);
729         }
730
731         DRW_uniformbuffer_update(sldata->light_ubo, &linfo->light_data);
732         DRW_uniformbuffer_update(sldata->shadow_ubo, &linfo->shadow_cube_data); /* Update all data at once */
733 }
734
735 /* this refresh lamps shadow buffers */
736 void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl)
737 {
738         EEVEE_LampsInfo *linfo = sldata->lamps;
739         Object *ob;
740         int i;
741         float clear_col[4] = {FLT_MAX};
742
743         /* Cube Shadow Maps */
744         /* Render each shadow to one layer of the array */
745         for (i = 0; (ob = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) {
746                 EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
747                 Lamp *la = (Lamp *)ob->data;
748
749                 if (led->need_update) {
750                         EEVEE_ShadowCubeData *evscd = (EEVEE_ShadowCubeData *)led->storage;
751                         EEVEE_ShadowRender *srd = &linfo->shadow_render_data;
752
753                         srd->shadow_samples_ct = 32.0f;
754                         srd->shadow_inv_samples_ct = 1.0f / srd->shadow_samples_ct;
755                         srd->clip_near = la->clipsta;
756                         srd->clip_far = la->clipend;
757                         copy_v3_v3(srd->position, ob->obmat[3]);
758                         for (int j = 0; j < 6; j++) {
759                                 float tmp[4][4];
760
761                                 unit_m4(tmp);
762                                 negate_v3_v3(tmp[3], ob->obmat[3]);
763                                 mul_m4_m4m4(srd->viewmat[j], cubefacemat[j], tmp);
764
765                                 copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]);
766                         }
767                         DRW_uniformbuffer_update(sldata->shadow_render_ubo, srd);
768
769                         DRW_framebuffer_texture_attach(sldata->shadow_target_fb, sldata->shadow_cube_target, 0, 0);
770                         DRW_framebuffer_bind(sldata->shadow_target_fb);
771                         DRW_framebuffer_clear(true, true, false, clear_col, 1.0f);
772                         /* Render shadow cube */
773                         DRW_draw_pass(psl->shadow_cube_pass);
774
775                         /* Push it to shadowmap array */
776                         DRW_framebuffer_texture_layer_attach(sldata->shadow_store_fb, sldata->shadow_pool, 0, i, 0);
777                         DRW_framebuffer_bind(sldata->shadow_store_fb);
778                         DRW_draw_pass(psl->shadow_cube_store_pass);
779
780                         led->need_update = false;
781                 }
782         }
783         linfo->update_flag &= ~LIGHT_UPDATE_SHADOW_CUBE;
784
785         DRW_framebuffer_texture_detach(sldata->shadow_cube_target);
786
787         /* Cascaded Shadow Maps */
788 //      DRW_framebuffer_bind(fbl->shadow_cascade_fb);
789 //      DRW_framebuffer_clear(false, true, false, NULL, 1.0);
790
791 //      /* Render each shadow to one layer of the array */
792 //      for (i = 0; (ob = linfo->shadow_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) {
793 //              EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob);
794 //              EEVEE_ShadowCascadeData *evscd = (EEVEE_ShadowCascadeData *)led->storage;
795 //              EEVEE_ShadowRender *srd = &linfo->shadow_render_data;
796
797 //              srd->layer = i;
798 //              for (int j = 0; j < MAX_CASCADE_NUM; ++j) {
799 //                      copy_m4_m4(srd->shadowmat[j], evscd->viewprojmat[j]);
800 //              }
801 //              DRW_uniformbuffer_update(sldata->shadow_render_ubo, &linfo->shadow_render_data);
802
803 //              DRW_draw_pass(psl->shadow_cascade_pass);
804 //      }
805 }
806
807 void EEVEE_lights_free(void)
808 {
809         DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
810         for (int i = 0; i < SHADOW_METHOD_MAX; ++i) {
811                 DRW_SHADER_FREE_SAFE(e_data.shadow_store_cube_sh[i]);
812                 DRW_SHADER_FREE_SAFE(e_data.shadow_store_cascade_sh[i]);
813         }
814 }