Rename any instance of scene layer or render layer in code with view layer
[blender.git] / source / blender / draw / engines / eevee / eevee_lightprobes.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_lightprobes.c
23  *  \ingroup DNA
24  */
25
26 #include "DRW_render.h"
27
28 #include "BLI_utildefines.h"
29 #include "BLI_dynstr.h"
30 #include "BLI_rand.h"
31
32 #include "DNA_world_types.h"
33 #include "DNA_texture_types.h"
34 #include "DNA_image_types.h"
35 #include "DNA_lightprobe_types.h"
36 #include "DNA_view3d_types.h"
37
38 #include "BKE_object.h"
39
40 #include "GPU_material.h"
41 #include "GPU_texture.h"
42 #include "GPU_glew.h"
43
44 #include "eevee_engine.h"
45 #include "eevee_private.h"
46
47 #include "ED_screen.h"
48
49 #define IRRADIANCE_POOL_SIZE 1024
50
51 static struct {
52         struct GPUShader *probe_default_sh;
53         struct GPUShader *probe_filter_glossy_sh;
54         struct GPUShader *probe_filter_diffuse_sh;
55         struct GPUShader *probe_grid_fill_sh;
56         struct GPUShader *probe_grid_display_sh;
57         struct GPUShader *probe_planar_display_sh;
58         struct GPUShader *probe_planar_downsample_sh;
59         struct GPUShader *probe_cube_display_sh;
60
61         struct GPUTexture *hammersley;
62         struct GPUTexture *planar_pool_placeholder;
63         struct GPUTexture *depth_placeholder;
64         struct GPUTexture *depth_array_placeholder;
65         struct GPUTexture *cube_face_depth;
66         struct GPUTexture *cube_face_minmaxz;
67
68         int update_world;
69         bool world_ready_to_shade;
70 } e_data = {NULL}; /* Engine data */
71
72 extern char datatoc_background_vert_glsl[];
73 extern char datatoc_default_world_frag_glsl[];
74 extern char datatoc_lightprobe_filter_glossy_frag_glsl[];
75 extern char datatoc_lightprobe_filter_diffuse_frag_glsl[];
76 extern char datatoc_lightprobe_geom_glsl[];
77 extern char datatoc_lightprobe_vert_glsl[];
78 extern char datatoc_lightprobe_planar_display_frag_glsl[];
79 extern char datatoc_lightprobe_planar_display_vert_glsl[];
80 extern char datatoc_lightprobe_planar_downsample_frag_glsl[];
81 extern char datatoc_lightprobe_planar_downsample_geom_glsl[];
82 extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
83 extern char datatoc_lightprobe_cube_display_frag_glsl[];
84 extern char datatoc_lightprobe_cube_display_vert_glsl[];
85 extern char datatoc_lightprobe_grid_display_frag_glsl[];
86 extern char datatoc_lightprobe_grid_display_vert_glsl[];
87 extern char datatoc_lightprobe_grid_fill_frag_glsl[];
88 extern char datatoc_irradiance_lib_glsl[];
89 extern char datatoc_lightprobe_lib_glsl[];
90 extern char datatoc_octahedron_lib_glsl[];
91 extern char datatoc_bsdf_common_lib_glsl[];
92 extern char datatoc_bsdf_sampling_lib_glsl[];
93
94 extern GlobalsUboStorage ts;
95
96 /* *********** FUNCTIONS *********** */
97
98 static struct GPUTexture *create_hammersley_sample_texture(int samples)
99 {
100         struct GPUTexture *tex;
101         float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex");
102         int i;
103
104         for (i = 0; i < samples; i++) {
105                 double dphi;
106                 BLI_hammersley_1D(i, &dphi);
107                 float phi = (float)dphi * 2.0f * M_PI;
108                 texels[i][0] = cosf(phi);
109                 texels[i][1] = sinf(phi);
110         }
111
112         tex = DRW_texture_create_1D(samples, DRW_TEX_RG_16, DRW_TEX_WRAP, (float *)texels);
113         MEM_freeN(texels);
114         return tex;
115 }
116
117 static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref)
118 {
119         /* XXX TODO OPTIMISATION : This is a complete waist of texture memory.
120          * Instead of allocating each planar probe for each viewport,
121          * only alloc them once using the biggest viewport resolution. */
122         EEVEE_FramebufferList *fbl = vedata->fbl;
123         EEVEE_TextureList *txl = vedata->txl;
124
125         const float *viewport_size = DRW_viewport_size_get();
126
127         /* TODO get screen percentage from layer setting */
128         // const DRWContextState *draw_ctx = DRW_context_state_get();
129         // ViewLayer *view_layer = draw_ctx->view_layer;
130         float screen_percentage = 1.0f;
131
132         int width = (int)(viewport_size[0] * screen_percentage);
133         int height = (int)(viewport_size[1] * screen_percentage);
134
135         /* We need an Array texture so allocate it ourself */
136         if (!txl->planar_pool) {
137                 if (num_planar_ref > 0) {
138                         txl->planar_pool = DRW_texture_create_2D_array(width, height, max_ff(1, num_planar_ref),
139                                                                          DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
140                         txl->planar_depth = DRW_texture_create_2D_array(width, height, max_ff(1, num_planar_ref),
141                                                                         DRW_TEX_DEPTH_24, 0, NULL);
142                 }
143                 else if (num_planar_ref == 0) {
144                         /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */
145                         txl->planar_pool = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_RGBA_8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
146                         txl->planar_depth = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_DEPTH_24, 0, NULL);
147                 }
148         }
149
150         if (num_planar_ref > 0) {
151                 /* NOTE : Depth buffer is 2D but the planar_pool tex is 2D array.
152                  * DRW_framebuffer_init binds the whole texture making the framebuffer invalid.
153                  * To overcome this, we bind the planar pool ourselves later */
154
155                 /* XXX Do this one first so it gets it's mipmap done. */
156                 DRW_framebuffer_init(&fbl->planarref_fb, &draw_engine_eevee_type, 1, 1, NULL, 0);
157         }
158 }
159
160 void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *UNUSED(vedata))
161 {
162         const DRWContextState *draw_ctx = DRW_context_state_get();
163         ViewLayer *view_layer = draw_ctx->view_layer;
164         IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
165
166         /* Shaders */
167         if (!e_data.probe_filter_glossy_sh) {
168                 char *shader_str = NULL;
169
170                 DynStr *ds_frag = BLI_dynstr_new();
171                 BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
172                 BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl);
173                 BLI_dynstr_append(ds_frag, datatoc_lightprobe_filter_glossy_frag_glsl);
174                 shader_str = BLI_dynstr_get_cstring(ds_frag);
175                 BLI_dynstr_free(ds_frag);
176
177                 e_data.probe_filter_glossy_sh = DRW_shader_create(
178                         datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, shader_str,
179                         "#define HAMMERSLEY_SIZE 1024\n"
180                         "#define NOISE_SIZE 64\n");
181
182                 e_data.probe_default_sh = DRW_shader_create(
183                         datatoc_background_vert_glsl, NULL, datatoc_default_world_frag_glsl, NULL);
184
185                 MEM_freeN(shader_str);
186
187                 ds_frag = BLI_dynstr_new();
188                 BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
189                 BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl);
190                 BLI_dynstr_append(ds_frag, datatoc_lightprobe_filter_diffuse_frag_glsl);
191                 shader_str = BLI_dynstr_get_cstring(ds_frag);
192                 BLI_dynstr_free(ds_frag);
193
194                 e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen(
195                         shader_str,
196 #if defined(IRRADIANCE_SH_L2)
197                         "#define IRRADIANCE_SH_L2\n"
198 #elif defined(IRRADIANCE_CUBEMAP)
199                         "#define IRRADIANCE_CUBEMAP\n"
200 #elif defined(IRRADIANCE_HL2)
201                         "#define IRRADIANCE_HL2\n"
202 #endif
203                         "#define HAMMERSLEY_SIZE 1024\n"
204                         "#define NOISE_SIZE 64\n");
205
206                 MEM_freeN(shader_str);
207
208                 ds_frag = BLI_dynstr_new();
209                 BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
210                 BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
211                 BLI_dynstr_append(ds_frag, datatoc_irradiance_lib_glsl);
212                 BLI_dynstr_append(ds_frag, datatoc_lightprobe_lib_glsl);
213                 BLI_dynstr_append(ds_frag, datatoc_lightprobe_grid_display_frag_glsl);
214                 shader_str = BLI_dynstr_get_cstring(ds_frag);
215                 BLI_dynstr_free(ds_frag);
216
217                 e_data.probe_grid_display_sh = DRW_shader_create(
218                         datatoc_lightprobe_grid_display_vert_glsl, NULL, shader_str,
219 #if defined(IRRADIANCE_SH_L2)
220                         "#define IRRADIANCE_SH_L2\n"
221 #elif defined(IRRADIANCE_CUBEMAP)
222                         "#define IRRADIANCE_CUBEMAP\n"
223 #elif defined(IRRADIANCE_HL2)
224                         "#define IRRADIANCE_HL2\n"
225 #endif
226                         );
227
228                 MEM_freeN(shader_str);
229
230                 e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen(datatoc_lightprobe_grid_fill_frag_glsl,
231 #if defined(IRRADIANCE_SH_L2)
232                         "#define IRRADIANCE_SH_L2\n"
233 #elif defined(IRRADIANCE_CUBEMAP)
234                         "#define IRRADIANCE_CUBEMAP\n"
235 #elif defined(IRRADIANCE_HL2)
236                         "#define IRRADIANCE_HL2\n"
237 #endif
238                         );
239
240                 ds_frag = BLI_dynstr_new();
241                 BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
242                 BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
243                 BLI_dynstr_append(ds_frag, datatoc_lightprobe_lib_glsl);
244                 BLI_dynstr_append(ds_frag, datatoc_lightprobe_cube_display_frag_glsl);
245                 shader_str = BLI_dynstr_get_cstring(ds_frag);
246                 BLI_dynstr_free(ds_frag);
247
248                 e_data.probe_cube_display_sh = DRW_shader_create(
249                         datatoc_lightprobe_cube_display_vert_glsl, NULL, shader_str, NULL);
250
251                 MEM_freeN(shader_str);
252
253                 e_data.probe_planar_display_sh = DRW_shader_create(
254                         datatoc_lightprobe_planar_display_vert_glsl, NULL,
255                         datatoc_lightprobe_planar_display_frag_glsl, NULL);
256
257                 e_data.probe_planar_downsample_sh = DRW_shader_create(
258                         datatoc_lightprobe_planar_downsample_vert_glsl,
259                         datatoc_lightprobe_planar_downsample_geom_glsl,
260                         datatoc_lightprobe_planar_downsample_frag_glsl,
261                         NULL);
262
263                 e_data.hammersley = create_hammersley_sample_texture(1024);
264         }
265
266         if (!sldata->probes) {
267                 sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo");
268                 sldata->probes->specular_toggle = true;
269                 sldata->probes->ssr_toggle = true;
270                 sldata->probes->grid_initialized = false;
271                 sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL);
272                 sldata->grid_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightGrid) * MAX_GRID, NULL);
273                 sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR, NULL);
274         }
275
276         int prop_bounce_num = BKE_collection_engine_property_value_get_int(props, "gi_diffuse_bounces");
277         /* Update all probes if number of bounces mismatch. */
278         if (sldata->probes->num_bounce != prop_bounce_num) {
279                 e_data.update_world |= PROBE_UPDATE_ALL;
280                 sldata->probes->updated_bounce = 0;
281                 sldata->probes->grid_initialized = false;
282         }
283         sldata->probes->num_bounce = prop_bounce_num;
284
285         int prop_cubemap_res = BKE_collection_engine_property_value_get_int(props, "gi_cubemap_resolution");
286         if (sldata->probes->cubemap_res != prop_cubemap_res) {
287                 sldata->probes->cubemap_res = prop_cubemap_res;
288
289                 e_data.update_world |= PROBE_UPDATE_ALL;
290                 sldata->probes->updated_bounce = 0;
291                 sldata->probes->grid_initialized = false;
292
293                 sldata->probes->target_size = prop_cubemap_res >> 1;
294
295                 DRW_TEXTURE_FREE_SAFE(sldata->probe_rt);
296                 DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
297         }
298
299         /* Setup Render Target Cubemap */
300
301         /* We do this detach / attach dance to not generate an invalid framebuffer (mixed cubemap / 2D map) */
302         if (sldata->probe_rt) {
303                 /* XXX Silly,TODO Cleanup this mess */
304                 DRW_framebuffer_texture_detach(sldata->probe_rt);
305         }
306
307         DRWFboTexture tex_probe = {&e_data.cube_face_depth, DRW_TEX_DEPTH_24, DRW_TEX_TEMP};
308         DRW_framebuffer_init(&sldata->probe_fb, &draw_engine_eevee_type, sldata->probes->target_size, sldata->probes->target_size, &tex_probe, 1);
309
310         if (!sldata->probe_rt) {
311                 sldata->probe_rt = DRW_texture_create_cube(sldata->probes->target_size, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
312         }
313
314         if (sldata->probe_rt) {
315                 /* XXX Silly,TODO Cleanup this mess */
316                 DRW_framebuffer_texture_attach(sldata->probe_fb, sldata->probe_rt, 0, 0);
317         }
318
319         /* Minmaxz Pyramid */
320         // DRWFboTexture tex_minmaxz = {&e_data.cube_face_minmaxz, DRW_TEX_RG_32, DRW_TEX_MIPMAP | DRW_TEX_TEMP};
321         // DRW_framebuffer_init(&vedata->fbl->downsample_fb, &draw_engine_eevee_type, PROBE_RT_SIZE / 2, PROBE_RT_SIZE / 2, &tex_minmaxz, 1);
322
323         /* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */
324         if (!e_data.planar_pool_placeholder) {
325                 e_data.planar_pool_placeholder = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_RGBA_8, DRW_TEX_FILTER, NULL);
326         }
327
328         if (!e_data.depth_placeholder) {
329                 e_data.depth_placeholder = DRW_texture_create_2D(1, 1, DRW_TEX_DEPTH_24, 0, NULL);
330         }
331         if (!e_data.depth_array_placeholder) {
332                 e_data.depth_array_placeholder = DRW_texture_create_2D_array(1, 1, 1, DRW_TEX_DEPTH_24, 0, NULL);
333         }
334 }
335
336 void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
337 {
338         EEVEE_TextureList *txl = vedata->txl;
339         EEVEE_PassList *psl = vedata->psl;
340         EEVEE_StorageList *stl = vedata->stl;
341         EEVEE_LightProbesInfo *pinfo = sldata->probes;
342
343         pinfo->num_cube = 1; /* at least one for the world */
344         pinfo->num_grid = 1;
345         pinfo->num_planar = 0;
346         memset(pinfo->probes_cube_ref, 0, sizeof(pinfo->probes_cube_ref));
347         memset(pinfo->probes_grid_ref, 0, sizeof(pinfo->probes_grid_ref));
348         memset(pinfo->probes_planar_ref, 0, sizeof(pinfo->probes_planar_ref));
349
350         {
351                 psl->probe_background = DRW_pass_create("World Probe Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
352
353                 struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
354                 DRWShadingGroup *grp = NULL;
355
356                 const DRWContextState *draw_ctx = DRW_context_state_get();
357                 Scene *scene = draw_ctx->scene;
358                 World *wo = scene->world;
359
360                 float *col = ts.colorBackground;
361                 if (wo) {
362                         col = &wo->horr;
363                         if (wo->update_flag != 0) {
364                                 e_data.update_world |= PROBE_UPDATE_ALL;
365                                 pinfo->updated_bounce = 0;
366                                 pinfo->grid_initialized = false;
367                         }
368                         wo->update_flag = 0;
369
370                         if (wo->use_nodes && wo->nodetree) {
371                                 struct GPUMaterial *gpumat = EEVEE_material_world_lightprobe_get(scene, wo);
372
373                                 grp = DRW_shgroup_material_create(gpumat, psl->probe_background);
374
375                                 if (grp) {
376                                         DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
377                                         DRW_shgroup_call_add(grp, geom, NULL);
378                                 }
379                                 else {
380                                         /* Shader failed : pink background */
381                                         static float pink[3] = {1.0f, 0.0f, 1.0f};
382                                         col = pink;
383                                 }
384                         }
385                 }
386
387                 /* Fallback if shader fails or if not using nodetree. */
388                 if (grp == NULL) {
389                         grp = DRW_shgroup_create(e_data.probe_default_sh, psl->probe_background);
390                         DRW_shgroup_uniform_vec3(grp, "color", col, 1);
391                         DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
392                         DRW_shgroup_call_add(grp, geom, NULL);
393                 }
394         }
395
396         {
397                 psl->probe_glossy_compute = DRW_pass_create("LightProbe Glossy Compute", DRW_STATE_WRITE_COLOR);
398
399                 struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
400
401                 DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.probe_filter_glossy_sh, psl->probe_glossy_compute, geom);
402                 DRW_shgroup_uniform_float(grp, "sampleCount", &sldata->probes->samples_ct, 1);
403                 DRW_shgroup_uniform_float(grp, "invSampleCount", &sldata->probes->invsamples_ct, 1);
404                 DRW_shgroup_uniform_float(grp, "roughnessSquared", &sldata->probes->roughness, 1);
405                 DRW_shgroup_uniform_float(grp, "lodFactor", &sldata->probes->lodfactor, 1);
406                 DRW_shgroup_uniform_float(grp, "lodMax", &sldata->probes->lod_rt_max, 1);
407                 DRW_shgroup_uniform_float(grp, "texelSize", &sldata->probes->texel_size, 1);
408                 DRW_shgroup_uniform_float(grp, "paddingSize", &sldata->probes->padding_size, 1);
409                 DRW_shgroup_uniform_int(grp, "Layer", &sldata->probes->layer, 1);
410                 DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
411                 // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
412                 DRW_shgroup_uniform_texture(grp, "probeHdr", sldata->probe_rt);
413
414                 DRW_shgroup_set_instance_count(grp, 1);
415         }
416
417         {
418                 psl->probe_diffuse_compute = DRW_pass_create("LightProbe Diffuse Compute", DRW_STATE_WRITE_COLOR);
419
420                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_filter_diffuse_sh, psl->probe_diffuse_compute);
421 #ifdef IRRADIANCE_SH_L2
422                 DRW_shgroup_uniform_int(grp, "probeSize", &sldata->probes->shres, 1);
423 #else
424                 DRW_shgroup_uniform_float(grp, "sampleCount", &sldata->probes->samples_ct, 1);
425                 DRW_shgroup_uniform_float(grp, "invSampleCount", &sldata->probes->invsamples_ct, 1);
426                 DRW_shgroup_uniform_float(grp, "lodFactor", &sldata->probes->lodfactor, 1);
427                 DRW_shgroup_uniform_float(grp, "lodMax", &sldata->probes->lod_rt_max, 1);
428                 DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
429 #endif
430                 DRW_shgroup_uniform_texture(grp, "probeHdr", sldata->probe_rt);
431
432                 struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
433                 DRW_shgroup_call_add(grp, geom, NULL);
434         }
435
436         {
437                 psl->probe_grid_fill = DRW_pass_create("LightProbe Grid Floodfill", DRW_STATE_WRITE_COLOR);
438
439                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.probe_grid_fill_sh, psl->probe_grid_fill);
440                 DRW_shgroup_uniform_buffer(grp, "gridTexture", &sldata->irradiance_pool);
441
442                 struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
443                 DRW_shgroup_call_add(grp, geom, NULL);
444         }
445
446         {
447                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK;
448                 psl->probe_display = DRW_pass_create("LightProbe Display", state);
449
450                 struct Gwn_Batch *geom = DRW_cache_sphere_get();
451                 DRWShadingGroup *grp = stl->g_data->cube_display_shgrp = DRW_shgroup_instance_create(e_data.probe_cube_display_sh, psl->probe_display, geom);
452                 DRW_shgroup_attrib_float(grp, "probe_id", 1); /* XXX this works because we are still uploading 4bytes and using the right stride */
453                 DRW_shgroup_attrib_float(grp, "probe_location", 3);
454                 DRW_shgroup_attrib_float(grp, "sphere_size", 1);
455                 DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
456                 DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool);
457
458                 geom = DRW_cache_quad_get();
459                 grp = stl->g_data->planar_display_shgrp = DRW_shgroup_instance_create(e_data.probe_planar_display_sh, psl->probe_display, geom);
460                 DRW_shgroup_attrib_float(grp, "probe_id", 1); /* XXX this works because we are still uploading 4bytes and using the right stride */
461                 DRW_shgroup_attrib_float(grp, "probe_mat", 16);
462                 DRW_shgroup_uniform_buffer(grp, "probePlanars", &txl->planar_pool);
463         }
464
465         {
466                 psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR);
467
468                 struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
469                 DRWShadingGroup *grp = stl->g_data->planar_downsample = DRW_shgroup_instance_create(e_data.probe_planar_downsample_sh, psl->probe_planar_downsample_ps, geom);
470                 DRW_shgroup_uniform_buffer(grp, "source", &txl->planar_pool);
471                 DRW_shgroup_uniform_float(grp, "fireflyFactor", &stl->effects->ssr_firefly_fac, 1);
472         }
473 }
474
475 void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
476 {
477         EEVEE_LightProbesInfo *pinfo = sldata->probes;
478         LightProbe *probe = (LightProbe *)ob->data;
479
480         /* Step 1 find all lamps in the scene and setup them */
481         if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) ||
482             (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE))
483         {
484                 printf("Too much probes in the scene !!!\n");
485                 return;
486         }
487
488         EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
489
490         ped->num_cell = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z;
491
492         if ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0) {
493                 ped->need_update = true;
494                 ped->probe_id = 0;
495
496                 if (probe->type == LIGHTPROBE_TYPE_GRID) {
497                         ped->updated_cells = 0;
498                         ped->updated_lvl = 0;
499                         pinfo->updated_bounce = 0;
500                         pinfo->grid_initialized = false;
501                 }
502         }
503
504         if (e_data.update_world) {
505                 ped->need_update = true;
506                 ped->updated_cells = 0;
507                 ped->updated_lvl = 0;
508                 ped->probe_id = 0;
509         }
510
511         if (probe->type == LIGHTPROBE_TYPE_CUBE) {
512                 pinfo->probes_cube_ref[pinfo->num_cube] = ob;
513                 pinfo->num_cube++;
514         }
515         else if (probe->type == LIGHTPROBE_TYPE_PLANAR) {
516                 pinfo->probes_planar_ref[pinfo->num_planar] = ob;
517                 pinfo->num_planar++;
518         }
519         else { /* GRID */
520                 pinfo->probes_grid_ref[pinfo->num_grid] = ob;
521                 pinfo->num_grid++;
522         }
523 }
524
525 /* TODO find a nice name to push it to math_matrix.c */
526 static void scale_m4_v3(float R[4][4], float v[3])
527 {
528         for (int i = 0; i < 4; ++i)
529                 mul_v3_v3(R[i], v);
530 }
531
532 static void EEVEE_planar_reflections_updates(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl)
533 {
534         EEVEE_LightProbesInfo *pinfo = sldata->probes;
535         Object *ob;
536         float mtx[4][4], normat[4][4], imat[4][4], rangemat[4][4];
537
538         float viewmat[4][4], winmat[4][4];
539         DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
540         DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
541
542         zero_m4(rangemat);
543         rangemat[0][0] = rangemat[1][1] = rangemat[2][2] = 0.5f;
544         rangemat[3][0] = rangemat[3][1] = rangemat[3][2] = 0.5f;
545         rangemat[3][3] = 1.0f;
546
547         /* PLANAR REFLECTION */
548         for (int i = 0; (ob = pinfo->probes_planar_ref[i]) && (i < MAX_PLANAR); i++) {
549                 LightProbe *probe = (LightProbe *)ob->data;
550                 EEVEE_PlanarReflection *eplanar = &pinfo->planar_data[i];
551                 EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
552
553                 /* Computing mtx : matrix that mirror position around object's XY plane. */
554                 normalize_m4_m4(normat, ob->obmat);  /* object > world */
555                 invert_m4_m4(imat, normat); /* world > object */
556
557                 float reflect[3] = {1.0f, 1.0f, -1.0f}; /* XY reflection plane */
558                 scale_m4_v3(imat, reflect); /* world > object > mirrored obj */
559                 mul_m4_m4m4(mtx, normat, imat); /* world > object > mirrored obj > world */
560
561                 /* Reflect Camera Matrix. */
562                 mul_m4_m4m4(ped->viewmat, viewmat, mtx);
563
564                 /* TODO FOV margin */
565                 float winmat_fov[4][4];
566                 copy_m4_m4(winmat_fov, winmat);
567
568                 /* Apply Perspective Matrix. */
569                 mul_m4_m4m4(ped->persmat, winmat_fov, ped->viewmat);
570
571                 /* This is the matrix used to reconstruct texture coordinates.
572                  * We use the original view matrix because it does not create
573                  * visual artifacts if receiver is not perfectly aligned with
574                  * the planar reflection probe. */
575                 mul_m4_m4m4(eplanar->reflectionmat, winmat_fov, viewmat); /* TODO FOV margin */
576                 /* Convert from [-1, 1] to [0, 1] (NDC to Texture coord). */
577                 mul_m4_m4m4(eplanar->reflectionmat, rangemat, eplanar->reflectionmat);
578
579                 /* TODO frustum check. */
580                 ped->need_update = true;
581
582                 /* Compute clip plane equation / normal. */
583                 float refpoint[3];
584                 copy_v3_v3(eplanar->plane_equation, ob->obmat[2]);
585                 normalize_v3(eplanar->plane_equation); /* plane normal */
586                 eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->obmat[3]);
587
588                 /* Compute offset plane equation (fix missing texels near reflection plane). */
589                 copy_v3_v3(ped->planer_eq_offset, eplanar->plane_equation);
590                 mul_v3_v3fl(refpoint, eplanar->plane_equation, -probe->clipsta);
591                 add_v3_v3(refpoint, ob->obmat[3]);
592                 ped->planer_eq_offset[3] = -dot_v3v3(eplanar->plane_equation, refpoint);
593
594                 /* Compute XY clip planes. */
595                 normalize_v3_v3(eplanar->clip_vec_x, ob->obmat[0]);
596                 normalize_v3_v3(eplanar->clip_vec_y, ob->obmat[1]);
597
598                 float vec[3] = {0.0f, 0.0f, 0.0f};
599                 vec[0] = 1.0f; vec[1] = 0.0f; vec[2] = 0.0f;
600                 mul_m4_v3(ob->obmat, vec); /* Point on the edge */
601                 eplanar->clip_edge_x_pos = dot_v3v3(eplanar->clip_vec_x, vec);
602
603                 vec[0] = 0.0f; vec[1] = 1.0f; vec[2] = 0.0f;
604                 mul_m4_v3(ob->obmat, vec); /* Point on the edge */
605                 eplanar->clip_edge_y_pos = dot_v3v3(eplanar->clip_vec_y, vec);
606
607                 vec[0] = -1.0f; vec[1] = 0.0f; vec[2] = 0.0f;
608                 mul_m4_v3(ob->obmat, vec); /* Point on the edge */
609                 eplanar->clip_edge_x_neg = dot_v3v3(eplanar->clip_vec_x, vec);
610
611                 vec[0] = 0.0f; vec[1] = -1.0f; vec[2] = 0.0f;
612                 mul_m4_v3(ob->obmat, vec); /* Point on the edge */
613                 eplanar->clip_edge_y_neg = dot_v3v3(eplanar->clip_vec_y, vec);
614
615                 /* Facing factors */
616                 float max_angle = max_ff(1e-2f, probe->falloff) * M_PI * 0.5f;
617                 float min_angle = 0.0f;
618                 eplanar->facing_scale = 1.0f / max_ff(1e-8f, cosf(min_angle) - cosf(max_angle));
619                 eplanar->facing_bias = -min_ff(1.0f - 1e-8f, cosf(max_angle)) * eplanar->facing_scale;
620
621                 /* Distance factors */
622                 float max_dist = probe->distinf;
623                 float min_dist = min_ff(1.0f - 1e-8f, 1.0f - probe->falloff) * probe->distinf;
624                 eplanar->attenuation_scale = -1.0f / max_ff(1e-8f, max_dist - min_dist);
625                 eplanar->attenuation_bias = max_dist * -eplanar->attenuation_scale;
626
627                 /* Debug Display */
628                 if (BKE_object_is_visible(ob) &&
629                     DRW_state_draw_support() &&
630                     (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA))
631                 {
632                         DRW_shgroup_call_dynamic_add(stl->g_data->planar_display_shgrp, &ped->probe_id, ob->obmat);
633                 }
634         }
635 }
636
637 static void EEVEE_lightprobes_updates(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl, EEVEE_StorageList *stl)
638 {
639         EEVEE_LightProbesInfo *pinfo = sldata->probes;
640         Object *ob;
641
642         /* CUBE REFLECTION */
643         for (int i = 1; (ob = pinfo->probes_cube_ref[i]) && (i < MAX_PROBE); i++) {
644                 LightProbe *probe = (LightProbe *)ob->data;
645                 EEVEE_LightProbe *eprobe = &pinfo->probe_data[i];
646                 EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
647
648                 /* Update transforms */
649                 copy_v3_v3(eprobe->position, ob->obmat[3]);
650
651                 /* Attenuation */
652                 eprobe->attenuation_type = probe->attenuation_type;
653                 eprobe->attenuation_fac = 1.0f / max_ff(1e-8f, probe->falloff);
654
655                 unit_m4(eprobe->attenuationmat);
656                 scale_m4_fl(eprobe->attenuationmat, probe->distinf);
657                 mul_m4_m4m4(eprobe->attenuationmat, ob->obmat, eprobe->attenuationmat);
658                 invert_m4(eprobe->attenuationmat);
659
660                 /* Parallax */
661                 float dist;
662                 if ((probe->flag & LIGHTPROBE_FLAG_CUSTOM_PARALLAX) != 0) {
663                         eprobe->parallax_type = probe->parallax_type;
664                         dist = probe->distpar;
665                 }
666                 else {
667                         eprobe->parallax_type = probe->attenuation_type;
668                         dist = probe->distinf;
669                 }
670
671                 unit_m4(eprobe->parallaxmat);
672                 scale_m4_fl(eprobe->parallaxmat, dist);
673                 mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat);
674                 invert_m4(eprobe->parallaxmat);
675
676                 /* Debug Display */
677                 if (BKE_object_is_visible(ob) &&
678                     DRW_state_draw_support() &&
679                     (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA))
680                 {
681                         ped->probe_size = probe->data_draw_size * 0.1f;
682                         DRW_shgroup_call_dynamic_add(
683                                     stl->g_data->cube_display_shgrp, &ped->probe_id, ob->obmat[3], &ped->probe_size);
684                 }
685         }
686
687         /* IRRADIANCE GRID */
688         int offset = 1; /* to account for the world probe */
689         for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_GRID); i++) {
690                 LightProbe *probe = (LightProbe *)ob->data;
691                 EEVEE_LightGrid *egrid = &pinfo->grid_data[i];
692                 EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
693
694                 /* Add one for level 0 */
695                 ped->max_lvl = 1.0f + floorf(log2f((float)MAX3(probe->grid_resolution_x,
696                                                                probe->grid_resolution_y,
697                                                                probe->grid_resolution_z)));
698
699                 egrid->offset = offset;
700                 float fac = 1.0f / max_ff(1e-8f, probe->falloff);
701                 egrid->attenuation_scale = fac / max_ff(1e-8f, probe->distinf);
702                 egrid->attenuation_bias = fac;
703
704                 /* Set offset for the next grid */
705                 offset += ped->num_cell;
706
707                 /* Update transforms */
708                 float cell_dim[3], half_cell_dim[3];
709                 cell_dim[0] = 2.0f / (float)(probe->grid_resolution_x);
710                 cell_dim[1] = 2.0f / (float)(probe->grid_resolution_y);
711                 cell_dim[2] = 2.0f / (float)(probe->grid_resolution_z);
712
713                 mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f);
714
715                 /* Matrix converting world space to cell ranges. */
716                 invert_m4_m4(egrid->mat, ob->obmat);
717
718                 /* First cell. */
719                 copy_v3_fl(egrid->corner, -1.0f);
720                 add_v3_v3(egrid->corner, half_cell_dim);
721                 mul_m4_v3(ob->obmat, egrid->corner);
722
723                 /* Opposite neighbor cell. */
724                 copy_v3_fl3(egrid->increment_x, cell_dim[0], 0.0f, 0.0f);
725                 add_v3_v3(egrid->increment_x, half_cell_dim);
726                 add_v3_fl(egrid->increment_x, -1.0f);
727                 mul_m4_v3(ob->obmat, egrid->increment_x);
728                 sub_v3_v3(egrid->increment_x, egrid->corner);
729
730                 copy_v3_fl3(egrid->increment_y, 0.0f, cell_dim[1], 0.0f);
731                 add_v3_v3(egrid->increment_y, half_cell_dim);
732                 add_v3_fl(egrid->increment_y, -1.0f);
733                 mul_m4_v3(ob->obmat, egrid->increment_y);
734                 sub_v3_v3(egrid->increment_y, egrid->corner);
735
736                 copy_v3_fl3(egrid->increment_z, 0.0f, 0.0f, cell_dim[2]);
737                 add_v3_v3(egrid->increment_z, half_cell_dim);
738                 add_v3_fl(egrid->increment_z, -1.0f);
739                 mul_m4_v3(ob->obmat, egrid->increment_z);
740                 sub_v3_v3(egrid->increment_z, egrid->corner);
741
742                 copy_v3_v3_int(egrid->resolution, &probe->grid_resolution_x);
743
744                 /* Debug Display */
745                 if (BKE_object_is_visible(ob) &&
746                     DRW_state_draw_support() &&
747                     (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA))
748                 {
749                         struct Gwn_Batch *geom = DRW_cache_sphere_get();
750                         DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.probe_grid_display_sh, psl->probe_display, geom);
751                         DRW_shgroup_set_instance_count(grp, ped->num_cell);
752                         DRW_shgroup_uniform_int(grp, "offset", &egrid->offset, 1);
753                         DRW_shgroup_uniform_ivec3(grp, "grid_resolution", egrid->resolution, 1);
754                         DRW_shgroup_uniform_vec3(grp, "corner", egrid->corner, 1);
755                         DRW_shgroup_uniform_vec3(grp, "increment_x", egrid->increment_x, 1);
756                         DRW_shgroup_uniform_vec3(grp, "increment_y", egrid->increment_y, 1);
757                         DRW_shgroup_uniform_vec3(grp, "increment_z", egrid->increment_z, 1);
758                         DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
759                         DRW_shgroup_uniform_float(grp, "sphere_size", &probe->data_draw_size, 1);
760                 }
761         }
762 }
763
764 void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
765 {
766         EEVEE_StorageList *stl = vedata->stl;
767         EEVEE_LightProbesInfo *pinfo = sldata->probes;
768         Object *ob;
769
770         /* Setup enough layers. */
771         /* Free textures if number mismatch. */
772         if (pinfo->num_cube != pinfo->cache_num_cube) {
773                 DRW_TEXTURE_FREE_SAFE(sldata->probe_pool);
774         }
775
776         if (pinfo->num_planar != pinfo->cache_num_planar) {
777                 DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_pool);
778                 DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_depth);
779                 pinfo->cache_num_planar = pinfo->num_planar;
780         }
781
782         /* XXX this should be run each frame as it ensure planar_depth is set */
783         planar_pool_ensure_alloc(vedata, pinfo->num_planar);
784
785         /* Setup planar filtering pass */
786         DRW_shgroup_set_instance_count(stl->g_data->planar_downsample, pinfo->num_planar);
787
788         if (!sldata->probe_pool) {
789                 sldata->probe_pool = DRW_texture_create_2D_array(pinfo->cubemap_res, pinfo->cubemap_res, max_ff(1, pinfo->num_cube),
790                                                                  DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
791                 if (sldata->probe_filter_fb) {
792                         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
793                 }
794
795                 /* Tag probes to refresh */
796                 e_data.update_world |= PROBE_UPDATE_CUBE;
797                 e_data.world_ready_to_shade = false;
798                 pinfo->num_render_cube = 0;
799                 pinfo->cache_num_cube = pinfo->num_cube;
800
801                 for (int i = 1; (ob = pinfo->probes_cube_ref[i]) && (i < MAX_PROBE); i++) {
802                         EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
803                         ped->need_update = true;
804                         ped->ready_to_shade = false;
805                         ped->probe_id = 0;
806                 }
807         }
808
809         DRWFboTexture tex_filter = {&sldata->probe_pool, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
810
811         DRW_framebuffer_init(&sldata->probe_filter_fb, &draw_engine_eevee_type, pinfo->cubemap_res, pinfo->cubemap_res, &tex_filter, 1);
812
813
814 #ifdef IRRADIANCE_SH_L2
815         /* we need a signed format for Spherical Harmonics */
816         int irradiance_format = DRW_TEX_RGBA_16;
817 #else
818         int irradiance_format = DRW_TEX_RGB_11_11_10;
819 #endif
820
821         /* TODO Allocate bigger storage if needed. */
822         if (!sldata->irradiance_pool || !sldata->irradiance_rt) {
823                 if (!sldata->irradiance_pool) {
824                         sldata->irradiance_pool = DRW_texture_create_2D(IRRADIANCE_POOL_SIZE, IRRADIANCE_POOL_SIZE, irradiance_format, DRW_TEX_FILTER, NULL);
825                 }
826                 if (!sldata->irradiance_rt) {
827                         sldata->irradiance_rt = DRW_texture_create_2D(IRRADIANCE_POOL_SIZE, IRRADIANCE_POOL_SIZE, irradiance_format, DRW_TEX_FILTER, NULL);
828                 }
829                 pinfo->num_render_grid = 0;
830                 pinfo->updated_bounce = 0;
831                 pinfo->grid_initialized = false;
832                 e_data.update_world |= PROBE_UPDATE_GRID;
833
834                 for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_PROBE); i++) {
835                         EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
836                         ped->need_update = true;
837                         ped->updated_cells = 0;
838                 }
839         }
840
841         if (pinfo->num_render_grid > pinfo->num_grid) {
842                 /* This can happen when deleting a probe. */
843                 pinfo->num_render_grid = pinfo->num_grid;
844         }
845
846         EEVEE_lightprobes_updates(sldata, vedata->psl, vedata->stl);
847         EEVEE_planar_reflections_updates(sldata, vedata->stl);
848
849         DRW_uniformbuffer_update(sldata->probe_ubo, &sldata->probes->probe_data);
850         DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
851         DRW_uniformbuffer_update(sldata->planar_ubo, &sldata->probes->planar_data);
852 }
853
854 static void downsample_planar(void *vedata, int level)
855 {
856         EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
857         EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
858
859         const float *size = DRW_viewport_size_get();
860         copy_v2_v2(stl->g_data->texel_size, size);
861         for (int i = 0; i < level - 1; ++i) {
862                 stl->g_data->texel_size[0] /= 2.0f;
863                 stl->g_data->texel_size[1] /= 2.0f;
864                 min_ff(floorf(stl->g_data->texel_size[0]), 1.0f);
865                 min_ff(floorf(stl->g_data->texel_size[1]), 1.0f);
866         }
867         invert_v2(stl->g_data->texel_size);
868
869         DRW_draw_pass(psl->probe_planar_downsample_ps);
870 }
871
872 /* Glossy filter probe_rt to probe_pool at index probe_idx */
873 static void glossy_filter_probe(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int probe_idx)
874 {
875         EEVEE_LightProbesInfo *pinfo = sldata->probes;
876
877         /* Max lod used from the render target probe */
878         pinfo->lod_rt_max = floorf(log2f(pinfo->target_size)) - 2.0f;
879
880         /* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */
881         /* Bind next framebuffer to be able to gen. mips for probe_rt. */
882         DRW_framebuffer_bind(sldata->probe_filter_fb);
883         EEVEE_downsample_cube_buffer(vedata, sldata->probe_filter_fb, sldata->probe_rt, (int)(pinfo->lod_rt_max));
884
885         /* 3 - Render to probe array to the specified layer, do prefiltering. */
886         /* Detach to rebind the right mipmap. */
887         DRW_framebuffer_texture_detach(sldata->probe_pool);
888         float mipsize = pinfo->cubemap_res;
889         const int maxlevel = (int)floorf(log2f(pinfo->cubemap_res));
890         const int min_lod_level = 3;
891         for (int i = 0; i < maxlevel - min_lod_level; i++) {
892                 float bias = (i == 0) ? -1.0f : 1.0f;
893                 pinfo->texel_size = 1.0f / mipsize;
894                 pinfo->padding_size = powf(2.0f, (float)(maxlevel - min_lod_level - 1 - i));
895                 /* XXX : WHY THE HECK DO WE NEED THIS ??? */
896                 /* padding is incorrect without this! float precision issue? */
897                 if (pinfo->padding_size > 32) {
898                         pinfo->padding_size += 5;
899                 }
900                 if (pinfo->padding_size > 16) {
901                         pinfo->padding_size += 4;
902                 }
903                 else if (pinfo->padding_size > 8) {
904                         pinfo->padding_size += 2;
905                 }
906                 else if (pinfo->padding_size > 4) {
907                         pinfo->padding_size += 1;
908                 }
909                 pinfo->layer = probe_idx;
910                 pinfo->roughness = (float)i / ((float)maxlevel - 4.0f);
911                 pinfo->roughness *= pinfo->roughness; /* Disney Roughness */
912                 pinfo->roughness *= pinfo->roughness; /* Distribute Roughness accros lod more evenly */
913                 CLAMP(pinfo->roughness, 1e-8f, 0.99999f); /* Avoid artifacts */
914
915 #if 1 /* Variable Sample count (fast) */
916                 switch (i) {
917                         case 0: pinfo->samples_ct = 1.0f; break;
918                         case 1: pinfo->samples_ct = 16.0f; break;
919                         case 2: pinfo->samples_ct = 32.0f; break;
920                         case 3: pinfo->samples_ct = 64.0f; break;
921                         default: pinfo->samples_ct = 128.0f; break;
922                 }
923 #else /* Constant Sample count (slow) */
924                 pinfo->samples_ct = 1024.0f;
925 #endif
926
927                 pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
928                 pinfo->lodfactor = bias + 0.5f * log((float)(pinfo->target_size * pinfo->target_size) * pinfo->invsamples_ct) / log(2);
929
930                 DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, i);
931                 DRW_framebuffer_viewport_size(sldata->probe_filter_fb, 0, 0, mipsize, mipsize);
932                 DRW_draw_pass(psl->probe_glossy_compute);
933                 DRW_framebuffer_texture_detach(sldata->probe_pool);
934
935                 mipsize /= 2;
936                 CLAMP_MIN(mipsize, 1);
937         }
938         /* For shading, save max level of the octahedron map */
939         pinfo->lod_cube_max = (float)(maxlevel - min_lod_level) - 1.0f;
940
941         /* reattach to have a valid framebuffer. */
942         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
943 }
944
945 /* Diffuse filter probe_rt to irradiance_pool at index probe_idx */
946 static void diffuse_filter_probe(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int offset)
947 {
948         EEVEE_LightProbesInfo *pinfo = sldata->probes;
949
950         /* find cell position on the virtual 3D texture */
951         /* NOTE : Keep in sync with load_irradiance_cell() */
952 #if defined(IRRADIANCE_SH_L2)
953         int size[2] = {3, 3};
954 #elif defined(IRRADIANCE_CUBEMAP)
955         int size[2] = {8, 8};
956         pinfo->samples_ct = 1024.0f;
957 #elif defined(IRRADIANCE_HL2)
958         int size[2] = {3, 2};
959         pinfo->samples_ct = 1024.0f;
960 #endif
961
962         int cell_per_row = IRRADIANCE_POOL_SIZE / size[0];
963         int x = size[0] * (offset % cell_per_row);
964         int y = size[1] * (offset / cell_per_row);
965
966 #ifndef IRRADIANCE_SH_L2
967         /* Tweaking parameters to balance perf. vs precision */
968         const float bias = 0.0f;
969         pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
970         pinfo->lodfactor = bias + 0.5f * log((float)(pinfo->target_size * pinfo->target_size) * pinfo->invsamples_ct) / log(2);
971         pinfo->lod_rt_max = floorf(log2f(pinfo->target_size)) - 2.0f;
972 #else
973         pinfo->shres = 32; /* Less texture fetches & reduce branches */
974         pinfo->lod_rt_max = 2.0f; /* Improve cache reuse */
975 #endif
976
977         /* 4 - Compute spherical harmonics */
978         DRW_framebuffer_bind(sldata->probe_filter_fb);
979         EEVEE_downsample_cube_buffer(vedata, sldata->probe_filter_fb, sldata->probe_rt, (int)(pinfo->lod_rt_max));
980
981         DRW_framebuffer_texture_detach(sldata->probe_pool);
982         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
983
984         DRW_framebuffer_viewport_size(sldata->probe_filter_fb, x, y, size[0], size[1]);
985         DRW_draw_pass(psl->probe_diffuse_compute);
986
987         /* reattach to have a valid framebuffer. */
988         DRW_framebuffer_texture_detach(sldata->irradiance_rt);
989         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
990 }
991
992 /* Render the scene to the probe_rt texture. */
993 static void render_scene_to_probe(
994         EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
995         const float pos[3], float clipsta, float clipend)
996 {
997         EEVEE_TextureList *txl = vedata->txl;
998         EEVEE_PassList *psl = vedata->psl;
999         EEVEE_StorageList *stl = vedata->stl;
1000         EEVEE_LightProbesInfo *pinfo = sldata->probes;
1001
1002         float winmat[4][4], wininv[4][4], posmat[4][4], tmp_ao_dist, tmp_ao_samples, tmp_ao_settings;
1003
1004         unit_m4(posmat);
1005
1006         /* Move to capture position */
1007         negate_v3_v3(posmat[3], pos);
1008
1009         /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
1010         sldata->probes->specular_toggle = false;
1011         sldata->probes->ssr_toggle = false;
1012
1013         /* Disable AO until we find a way to hide really bad discontinuities between cubefaces. */
1014         tmp_ao_dist = stl->effects->ao_dist;
1015         tmp_ao_samples = stl->effects->ao_samples;
1016         tmp_ao_settings = stl->effects->ao_settings;
1017         stl->effects->ao_settings = 0.0f; /* Disable AO */
1018
1019         /* 1 - Render to each cubeface individually.
1020          * We do this instead of using geometry shader because a) it's faster,
1021          * b) it's easier than fixing the nodetree shaders (for view dependant effects). */
1022         pinfo->layer = 0;
1023         perspective_m4(winmat, -clipsta, clipsta, -clipsta, clipsta, clipsta, clipend);
1024
1025         /* Avoid using the texture attached to framebuffer when rendering. */
1026         /* XXX */
1027         GPUTexture *tmp_planar_pool = txl->planar_pool;
1028         GPUTexture *tmp_minz = stl->g_data->minzbuffer;
1029         GPUTexture *tmp_maxz = txl->maxzbuffer;
1030         txl->planar_pool = e_data.planar_pool_placeholder;
1031         stl->g_data->minzbuffer = e_data.depth_placeholder;
1032         txl->maxzbuffer = e_data.depth_placeholder;
1033
1034         /* Detach to rebind the right cubeface. */
1035         DRW_framebuffer_bind(sldata->probe_fb);
1036         DRW_framebuffer_texture_attach(sldata->probe_fb, e_data.cube_face_depth, 0, 0);
1037         DRW_framebuffer_texture_detach(sldata->probe_rt);
1038         for (int i = 0; i < 6; ++i) {
1039                 float viewmat[4][4], persmat[4][4];
1040                 float viewinv[4][4], persinv[4][4];
1041
1042                 /* Setup custom matrices */
1043                 mul_m4_m4m4(viewmat, cubefacemat[i], posmat);
1044                 mul_m4_m4m4(persmat, winmat, viewmat);
1045                 invert_m4_m4(persinv, persmat);
1046                 invert_m4_m4(viewinv, viewmat);
1047                 invert_m4_m4(wininv, winmat);
1048
1049                 DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
1050                 DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV);
1051                 DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW);
1052                 DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV);
1053                 DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
1054                 DRW_viewport_matrix_override_set(wininv, DRW_MAT_WININV);
1055
1056                 /* Be sure that cascaded shadow maps are updated. */
1057                 EEVEE_draw_shadows(sldata, psl);
1058
1059                 DRW_framebuffer_cubeface_attach(sldata->probe_fb, sldata->probe_rt, 0, i, 0);
1060                 DRW_framebuffer_viewport_size(sldata->probe_fb, 0, 0, pinfo->target_size, pinfo->target_size);
1061
1062                 DRW_framebuffer_clear(false, true, false, NULL, 1.0);
1063
1064                 /* Depth prepass */
1065                 DRW_draw_pass(psl->depth_pass);
1066                 DRW_draw_pass(psl->depth_pass_cull);
1067
1068                 DRW_draw_pass(psl->probe_background);
1069
1070                 // EEVEE_create_minmax_buffer(vedata, e_data.cube_face_depth);
1071
1072                 /* Rebind Planar FB */
1073                 DRW_framebuffer_bind(sldata->probe_fb);
1074
1075                 /* Shading pass */
1076                 EEVEE_draw_default_passes(psl);
1077                 DRW_draw_pass(psl->material_pass);
1078                 DRW_draw_pass(psl->sss_pass); /* Only output standard pass */
1079
1080                 DRW_framebuffer_texture_detach(sldata->probe_rt);
1081         }
1082         DRW_framebuffer_texture_attach(sldata->probe_fb, sldata->probe_rt, 0, 0);
1083         DRW_framebuffer_texture_detach(e_data.cube_face_depth);
1084
1085         DRW_viewport_matrix_override_unset(DRW_MAT_PERS);
1086         DRW_viewport_matrix_override_unset(DRW_MAT_PERSINV);
1087         DRW_viewport_matrix_override_unset(DRW_MAT_VIEW);
1088         DRW_viewport_matrix_override_unset(DRW_MAT_VIEWINV);
1089         DRW_viewport_matrix_override_unset(DRW_MAT_WIN);
1090         DRW_viewport_matrix_override_unset(DRW_MAT_WININV);
1091
1092         /* Restore */
1093         pinfo->specular_toggle = true;
1094         pinfo->ssr_toggle = true;
1095         txl->planar_pool = tmp_planar_pool;
1096         stl->g_data->minzbuffer = tmp_minz;
1097         txl->maxzbuffer = tmp_maxz;
1098         stl->effects->ao_dist = tmp_ao_dist;
1099         stl->effects->ao_samples = tmp_ao_samples;
1100         stl->effects->ao_settings = tmp_ao_settings;
1101 }
1102
1103 static void render_scene_to_planar(
1104         EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, int layer,
1105         float (*viewmat)[4], float (*persmat)[4],
1106         float clip_plane[4])
1107 {
1108         EEVEE_FramebufferList *fbl = vedata->fbl;
1109         EEVEE_TextureList *txl = vedata->txl;
1110         EEVEE_PassList *psl = vedata->psl;
1111
1112         float viewinv[4][4];
1113         float persinv[4][4];
1114
1115         invert_m4_m4(viewinv, viewmat);
1116         invert_m4_m4(persinv, persmat);
1117
1118         DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
1119         DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV);
1120         DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW);
1121         DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV);
1122
1123         /* Since we are rendering with an inverted view matrix, we need
1124          * to invert the facing for backface culling to be the same. */
1125         DRW_state_invert_facing();
1126
1127         /* Be sure that cascaded shadow maps are updated. */
1128         EEVEE_draw_shadows(sldata, psl);
1129
1130         DRW_state_clip_planes_add(clip_plane);
1131
1132         /* Attach depth here since it's a DRW_TEX_TEMP */
1133         DRW_framebuffer_texture_layer_attach(fbl->planarref_fb, txl->planar_depth, 0, layer, 0);
1134         DRW_framebuffer_texture_layer_attach(fbl->planarref_fb, txl->planar_pool, 0, layer, 0);
1135         DRW_framebuffer_bind(fbl->planarref_fb);
1136
1137         DRW_framebuffer_clear(false, true, false, NULL, 1.0);
1138
1139         /* Turn off ssr to avoid black specular */
1140         /* TODO : Enable SSR in planar reflections? (Would be very heavy) */
1141         sldata->probes->ssr_toggle = false;
1142
1143         /* Avoid using the texture attached to framebuffer when rendering. */
1144         /* XXX */
1145         GPUTexture *tmp_planar_pool = txl->planar_pool;
1146         GPUTexture *tmp_planar_depth = txl->planar_depth;
1147         txl->planar_pool = e_data.planar_pool_placeholder;
1148         txl->planar_depth = e_data.depth_array_placeholder;
1149
1150         /* Depth prepass */
1151         DRW_draw_pass(psl->depth_pass_clip);
1152         DRW_draw_pass(psl->depth_pass_clip_cull);
1153
1154         /* Background */
1155         DRW_draw_pass(psl->probe_background);
1156
1157         EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer);
1158
1159         /* Compute GTAO Horizons */
1160         EEVEE_occlusion_compute(sldata, vedata);
1161
1162         /* Rebind Planar FB */
1163         DRW_framebuffer_bind(fbl->planarref_fb);
1164
1165         /* Shading pass */
1166         EEVEE_draw_default_passes(psl);
1167         DRW_draw_pass(psl->material_pass);
1168         DRW_draw_pass(psl->sss_pass); /* Only output standard pass */
1169
1170         DRW_state_invert_facing();
1171         DRW_state_clip_planes_reset();
1172
1173         /* Restore */
1174         sldata->probes->ssr_toggle = true;
1175         txl->planar_pool = tmp_planar_pool;
1176         txl->planar_depth = tmp_planar_depth;
1177         DRW_viewport_matrix_override_unset(DRW_MAT_PERS);
1178         DRW_viewport_matrix_override_unset(DRW_MAT_PERSINV);
1179         DRW_viewport_matrix_override_unset(DRW_MAT_VIEW);
1180         DRW_viewport_matrix_override_unset(DRW_MAT_VIEWINV);
1181
1182         DRW_framebuffer_texture_detach(txl->planar_pool);
1183         DRW_framebuffer_texture_detach(txl->planar_depth);
1184 }
1185
1186 static void render_world_to_probe(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
1187 {
1188         EEVEE_LightProbesInfo *pinfo = sldata->probes;
1189         float winmat[4][4], wininv[4][4];
1190
1191         /* 1 - Render to cubemap target using geometry shader. */
1192         /* For world probe, we don't need to clear since we render the background directly. */
1193         pinfo->layer = 0;
1194
1195         perspective_m4(winmat, -0.1f, 0.1f, -0.1f, 0.1f, 0.1f, 1.0f);
1196         invert_m4_m4(wininv, winmat);
1197
1198         /* Detach to rebind the right cubeface. */
1199         DRW_framebuffer_bind(sldata->probe_fb);
1200         DRW_framebuffer_texture_detach(sldata->probe_rt);
1201         for (int i = 0; i < 6; ++i) {
1202                 float viewmat[4][4], persmat[4][4];
1203                 float viewinv[4][4], persinv[4][4];
1204
1205                 DRW_framebuffer_cubeface_attach(sldata->probe_fb, sldata->probe_rt, 0, i, 0);
1206                 DRW_framebuffer_viewport_size(sldata->probe_fb, 0, 0, pinfo->target_size, pinfo->target_size);
1207
1208                 /* Setup custom matrices */
1209                 copy_m4_m4(viewmat, cubefacemat[i]);
1210                 mul_m4_m4m4(persmat, winmat, viewmat);
1211                 invert_m4_m4(persinv, persmat);
1212                 invert_m4_m4(viewinv, viewmat);
1213
1214                 DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS);
1215                 DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV);
1216                 DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW);
1217                 DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV);
1218                 DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN);
1219                 DRW_viewport_matrix_override_set(wininv, DRW_MAT_WININV);
1220
1221                 DRW_draw_pass(psl->probe_background);
1222
1223                 DRW_framebuffer_texture_detach(sldata->probe_rt);
1224         }
1225         DRW_framebuffer_texture_attach(sldata->probe_fb, sldata->probe_rt, 0, 0);
1226
1227         DRW_viewport_matrix_override_unset(DRW_MAT_PERS);
1228         DRW_viewport_matrix_override_unset(DRW_MAT_PERSINV);
1229         DRW_viewport_matrix_override_unset(DRW_MAT_VIEW);
1230         DRW_viewport_matrix_override_unset(DRW_MAT_VIEWINV);
1231         DRW_viewport_matrix_override_unset(DRW_MAT_WIN);
1232         DRW_viewport_matrix_override_unset(DRW_MAT_WININV);
1233 }
1234
1235 static void lightprobe_cell_grid_location_get(EEVEE_LightGrid *egrid, int cell_idx, float r_local_cell[3])
1236 {
1237         /* Keep in sync with lightprobe_grid_display_vert */
1238         r_local_cell[2] = (float)(cell_idx % egrid->resolution[2]);
1239         r_local_cell[1] = (float)((cell_idx / egrid->resolution[2]) % egrid->resolution[1]);
1240         r_local_cell[0] = (float)(cell_idx / (egrid->resolution[2] * egrid->resolution[1]));
1241 }
1242
1243 static void lightprobe_cell_world_location_get(EEVEE_LightGrid *egrid, float local_cell[3], float r_pos[3])
1244 {
1245         float tmp[3];
1246
1247         copy_v3_v3(r_pos, egrid->corner);
1248         mul_v3_v3fl(tmp, egrid->increment_x, local_cell[0]);
1249         add_v3_v3(r_pos, tmp);
1250         mul_v3_v3fl(tmp, egrid->increment_y, local_cell[1]);
1251         add_v3_v3(r_pos, tmp);
1252         mul_v3_v3fl(tmp, egrid->increment_z, local_cell[2]);
1253         add_v3_v3(r_pos, tmp);
1254 }
1255
1256 void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
1257 {
1258         EEVEE_TextureList *txl = vedata->txl;
1259         EEVEE_PassList *psl = vedata->psl;
1260         EEVEE_StorageList *stl = vedata->stl;
1261         EEVEE_LightProbesInfo *pinfo = sldata->probes;
1262         Object *ob;
1263         const DRWContextState *draw_ctx = DRW_context_state_get();
1264         RegionView3D *rv3d = draw_ctx->rv3d;
1265
1266         /* Render world in priority */
1267         if (e_data.update_world) {
1268                 render_world_to_probe(sldata, psl);
1269
1270                 if (e_data.update_world & PROBE_UPDATE_CUBE) {
1271                         glossy_filter_probe(sldata, vedata, psl, 0);
1272                 }
1273
1274                 if (e_data.update_world & PROBE_UPDATE_GRID) {
1275                         diffuse_filter_probe(sldata, vedata, psl, 0);
1276
1277                         SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
1278
1279                         DRW_framebuffer_texture_detach(sldata->probe_pool);
1280
1281                         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
1282                         DRW_draw_pass(psl->probe_grid_fill);
1283                         DRW_framebuffer_texture_detach(sldata->irradiance_rt);
1284
1285                         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
1286                 }
1287
1288                 e_data.update_world = 0;
1289
1290                 if (!e_data.world_ready_to_shade) {
1291                         e_data.world_ready_to_shade = true;
1292                         pinfo->num_render_cube = 1;
1293                         pinfo->num_render_grid = 1;
1294                 }
1295
1296                 DRW_viewport_request_redraw();
1297         }
1298         else if (true) { /* TODO if at least one probe needs refresh */
1299
1300                 if (draw_ctx->evil_C != NULL) {
1301                         /* Only compute probes if not navigating or in playback */
1302                         struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
1303                         if (((rv3d->rflag & RV3D_NAVIGATING) != 0) || ED_screen_animation_no_scrub(wm) != NULL) {
1304                                 goto update_planar;
1305                         }
1306                 }
1307
1308                 if (!pinfo->grid_initialized) {
1309                         DRW_framebuffer_texture_detach(sldata->probe_pool);
1310
1311                         /* Flood fill with world irradiance. */
1312                         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
1313                         DRW_draw_pass(psl->probe_grid_fill);
1314                         DRW_framebuffer_texture_detach(sldata->irradiance_rt);
1315
1316                         SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
1317
1318                         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
1319                         DRW_draw_pass(psl->probe_grid_fill);
1320                         DRW_framebuffer_texture_detach(sldata->irradiance_rt);
1321
1322                         SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
1323
1324                         /* reattach to have a valid framebuffer. */
1325                         DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
1326
1327                         pinfo->grid_initialized = true;
1328                 }
1329
1330                 /* Reflection probes depend on diffuse lighting thus on irradiance grid,
1331                  * so update them first. */
1332                 while (pinfo->updated_bounce < pinfo->num_bounce) {
1333                         pinfo->num_render_grid = pinfo->num_grid;
1334
1335                         for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_GRID); i++) {
1336                                 EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
1337
1338                                 if (ped->need_update) {
1339                                         EEVEE_LightGrid *egrid = &pinfo->grid_data[i];
1340                                         LightProbe *prb = (LightProbe *)ob->data;
1341
1342                                         /* Find the next cell corresponding to the current level. */
1343                                         bool valid_cell = false;
1344                                         int cell_id = ped->updated_cells;
1345                                         float pos[3], grid_loc[3];
1346
1347                                         /* Other levels */
1348                                         int current_stride = 1 << max_ii(0, ped->max_lvl - ped->updated_lvl);
1349                                         int prev_stride = current_stride << 1;
1350
1351                                         while (!valid_cell) {
1352                                                 cell_id = ped->updated_cells;
1353                                                 lightprobe_cell_grid_location_get(egrid, cell_id, grid_loc);
1354
1355                                                 if (ped->updated_lvl == 0 && cell_id == 0) {
1356                                                         valid_cell = true;
1357                                                         ped->updated_cells = ped->num_cell;
1358                                                         continue;
1359                                                 }
1360                                                 else if (((((int)grid_loc[0] % current_stride) == 0) &&
1361                                                           (((int)grid_loc[1] % current_stride) == 0) &&
1362                                                           (((int)grid_loc[2] % current_stride) == 0)) &&
1363                                                          !((((int)grid_loc[0] % prev_stride) == 0) &&
1364                                                            (((int)grid_loc[1] % prev_stride) == 0) &&
1365                                                            (((int)grid_loc[2] % prev_stride) == 0)))
1366                                                 {
1367                                                         valid_cell = true;
1368                                                 }
1369
1370                                                 ped->updated_cells++;
1371
1372                                                 if (ped->updated_cells > ped->num_cell) {
1373                                                         goto skip_rendering;
1374                                                 }
1375                                         }
1376
1377                                         lightprobe_cell_world_location_get(egrid, grid_loc, pos);
1378
1379                                         SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
1380
1381                                         /* Temporary Remove all probes. */
1382                                         int tmp_num_render_grid = pinfo->num_render_grid;
1383                                         int tmp_num_render_cube = pinfo->num_render_cube;
1384                                         int tmp_num_planar = pinfo->num_planar;
1385                                         pinfo->num_render_cube = 0;
1386                                         pinfo->num_planar = 0;
1387
1388                                         /* Use light from previous bounce when capturing radiance. */
1389                                         if (pinfo->updated_bounce == 0) {
1390                                                 pinfo->num_render_grid = 0;
1391                                         }
1392
1393                                         render_scene_to_probe(sldata, vedata, pos, prb->clipsta, prb->clipend);
1394                                         diffuse_filter_probe(sldata, vedata, psl, egrid->offset + cell_id);
1395
1396                                         /* To see what is going on. */
1397                                         SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
1398
1399                                         /* Restore */
1400                                         pinfo->num_render_grid = tmp_num_render_grid;
1401                                         pinfo->num_render_cube = tmp_num_render_cube;
1402                                         pinfo->num_planar = tmp_num_planar;
1403
1404 skip_rendering:
1405
1406                                         if (ped->updated_cells >= ped->num_cell) {
1407                                                 ped->updated_lvl++;
1408                                                 ped->updated_cells = 0;
1409
1410                                                 if (ped->updated_lvl > ped->max_lvl) {
1411                                                         ped->need_update = false;
1412                                                 }
1413
1414                                                 egrid->level_bias = (float)(1 << max_ii(0, ped->max_lvl - ped->updated_lvl + 1));
1415                                                 DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
1416                                         }
1417 #if 0
1418                                         printf("Updated Grid %d : cell %d / %d, bounce %d / %d\n",
1419                                                 i, ped->updated_cells, ped->num_cell, pinfo->updated_bounce + 1, pinfo->num_bounce);
1420 #endif
1421                                         /* Only do one probe per frame */
1422                                         DRW_viewport_request_redraw();
1423                                         /* Do not let this frame accumulate. */
1424                                         stl->effects->taa_current_sample = 1;
1425
1426                                         goto update_planar;
1427                                 }
1428                         }
1429
1430                         pinfo->updated_bounce++;
1431                         pinfo->num_render_grid = pinfo->num_grid;
1432
1433                         if (pinfo->updated_bounce < pinfo->num_bounce) {
1434                                 /* Retag all grids to update for next bounce */
1435                                 for (int i = 1; (ob = pinfo->probes_grid_ref[i]) && (i < MAX_GRID); i++) {
1436                                         EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
1437                                         ped->need_update = true;
1438                                         ped->updated_cells = 0;
1439                                         ped->updated_lvl = 0;
1440                                 }
1441
1442                                 SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
1443
1444                                 /* Reset the next buffer so we can see the progress. */
1445                                 DRW_framebuffer_texture_detach(sldata->probe_pool);
1446
1447                                 DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
1448                                 DRW_draw_pass(psl->probe_grid_fill);
1449                                 DRW_framebuffer_texture_detach(sldata->irradiance_rt);
1450
1451                                 DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, 0);
1452                         }
1453                 }
1454
1455                 for (int i = 1; (ob = pinfo->probes_cube_ref[i]) && (i < MAX_PROBE); i++) {
1456                         EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
1457
1458                         if (ped->need_update) {
1459                                 LightProbe *prb = (LightProbe *)ob->data;
1460
1461                                 render_scene_to_probe(sldata, vedata, ob->obmat[3], prb->clipsta, prb->clipend);
1462                                 glossy_filter_probe(sldata, vedata, psl, i);
1463
1464                                 ped->need_update = false;
1465                                 ped->probe_id = i;
1466
1467                                 if (!ped->ready_to_shade) {
1468                                         pinfo->num_render_cube++;
1469                                         ped->ready_to_shade = true;
1470                                 }
1471 #if 0
1472                                 printf("Update Cubemap %d\n", i);
1473 #endif
1474                                 DRW_viewport_request_redraw();
1475                                 /* Do not let this frame accumulate. */
1476                                 stl->effects->taa_current_sample = 1;
1477
1478                                 /* Only do one probe per frame */
1479                                 goto update_planar;
1480                         }
1481                 }
1482         }
1483
1484 update_planar:
1485
1486         for (int i = 0; (ob = pinfo->probes_planar_ref[i]) && (i < MAX_PLANAR); i++) {
1487                 EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(ob);
1488
1489                 if (ped->need_update) {
1490                         /* Temporary Remove all planar reflections (avoid lag effect). */
1491                         int tmp_num_planar = pinfo->num_planar;
1492                         pinfo->num_planar = 0;
1493
1494                         render_scene_to_planar(sldata, vedata, i, ped->viewmat, ped->persmat, ped->planer_eq_offset);
1495
1496                         /* Restore */
1497                         pinfo->num_planar = tmp_num_planar;
1498
1499                         ped->need_update = false;
1500                         ped->probe_id = i;
1501                 }
1502         }
1503
1504         /* If there is at least one planar probe */
1505         if (pinfo->num_planar > 0 && (vedata->stl->effects->enabled_effects & EFFECT_SSR) != 0) {
1506                 const int max_lod = 9;
1507                 DRW_stats_group_start("Planar Probe Downsample");
1508                 DRW_framebuffer_recursive_downsample(vedata->fbl->downsample_fb, txl->planar_pool, max_lod, &downsample_planar, vedata);
1509                 /* For shading, save max level of the planar map */
1510                 pinfo->lod_planar_max = (float)(max_lod);
1511                 DRW_stats_group_end();
1512         }
1513 }
1514
1515 void EEVEE_lightprobes_free(void)
1516 {
1517         DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
1518         DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
1519         DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
1520         DRW_SHADER_FREE_SAFE(e_data.probe_grid_fill_sh);
1521         DRW_SHADER_FREE_SAFE(e_data.probe_grid_display_sh);
1522         DRW_SHADER_FREE_SAFE(e_data.probe_planar_display_sh);
1523         DRW_SHADER_FREE_SAFE(e_data.probe_planar_downsample_sh);
1524         DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh);
1525         DRW_TEXTURE_FREE_SAFE(e_data.hammersley);
1526         DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder);
1527         DRW_TEXTURE_FREE_SAFE(e_data.depth_placeholder);
1528         DRW_TEXTURE_FREE_SAFE(e_data.depth_array_placeholder);
1529 }