Cleanup: misc spelling fixes
[blender.git] / source / blender / draw / engines / eevee / eevee_lightprobes.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18
19 /** \file
20  * \ingroup draw_engine
21  */
22
23 #include "DRW_render.h"
24
25 #include "BLI_utildefines.h"
26 #include "BLI_rand.h"
27
28 #include "DNA_world_types.h"
29 #include "DNA_texture_types.h"
30 #include "DNA_image_types.h"
31 #include "DNA_lightprobe_types.h"
32 #include "DNA_view3d_types.h"
33
34 #include "BKE_collection.h"
35 #include "BKE_object.h"
36 #include "MEM_guardedalloc.h"
37
38 #include "GPU_material.h"
39 #include "GPU_texture.h"
40
41 #include "DEG_depsgraph_query.h"
42
43 #include "eevee_lightcache.h"
44 #include "eevee_private.h"
45
46 #include "WM_api.h"
47 #include "WM_types.h"
48
49 static struct {
50   struct GPUTexture *hammersley;
51   struct GPUTexture *planar_pool_placeholder;
52   struct GPUTexture *depth_placeholder;
53   struct GPUTexture *depth_array_placeholder;
54   struct GPUTexture *cube_face_minmaxz;
55
56   struct GPUVertFormat *format_probe_display_cube;
57   struct GPUVertFormat *format_probe_display_planar;
58 } e_data = {NULL}; /* Engine data */
59
60 /* *********** FUNCTIONS *********** */
61
62 /* TODO find a better way than this. This does not support dupli objects if
63  * the original object is hidden. */
64 bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data)
65 {
66   EEVEE_ObjectEngineData *oed = (EEVEE_ObjectEngineData *)user_data;
67
68   /* test disabled if group is NULL */
69   if (oed == NULL || oed->test_data->collection == NULL) {
70     return vis_in;
71   }
72
73   if (oed->test_data->cached == false) {
74     oed->ob_vis_dirty = true;
75   }
76
77   /* early out, don't need to compute ob_vis yet. */
78   if (vis_in == false) {
79     return vis_in;
80   }
81
82   if (oed->ob_vis_dirty) {
83     oed->ob_vis_dirty = false;
84     oed->ob_vis = BKE_collection_has_object_recursive(oed->test_data->collection, oed->ob);
85     oed->ob_vis = (oed->test_data->invert) ? !oed->ob_vis : oed->ob_vis;
86   }
87
88   return vis_in && oed->ob_vis;
89 }
90
91 static struct GPUTexture *create_hammersley_sample_texture(int samples)
92 {
93   struct GPUTexture *tex;
94   float(*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex");
95   int i;
96
97   for (i = 0; i < samples; i++) {
98     double dphi;
99     BLI_hammersley_1d(i, &dphi);
100     float phi = (float)dphi * 2.0f * M_PI;
101     texels[i][0] = cosf(phi);
102     texels[i][1] = sinf(phi);
103   }
104
105   tex = DRW_texture_create_1d(samples, GPU_RG16F, DRW_TEX_WRAP, (float *)texels);
106   MEM_freeN(texels);
107   return tex;
108 }
109
110 static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref)
111 {
112   EEVEE_TextureList *txl = vedata->txl;
113
114   /* XXX TODO OPTIMISATION : This is a complete waist of texture memory.
115    * Instead of allocating each planar probe for each viewport,
116    * only alloc them once using the biggest viewport resolution. */
117   const float *viewport_size = DRW_viewport_size_get();
118
119   /* TODO get screen percentage from layer setting */
120   // const DRWContextState *draw_ctx = DRW_context_state_get();
121   // ViewLayer *view_layer = draw_ctx->view_layer;
122   float screen_percentage = 1.0f;
123
124   int width = max_ii(1, (int)(viewport_size[0] * screen_percentage));
125   int height = max_ii(1, (int)(viewport_size[1] * screen_percentage));
126
127   /* Fix case were the pool was allocated width the dummy size (1,1,1). */
128   if (txl->planar_pool && (num_planar_ref > 0) &&
129       (GPU_texture_width(txl->planar_pool) != width ||
130        GPU_texture_height(txl->planar_pool) != height)) {
131     DRW_TEXTURE_FREE_SAFE(txl->planar_pool);
132     DRW_TEXTURE_FREE_SAFE(txl->planar_depth);
133   }
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,
139                                                      height,
140                                                      max_ii(1, num_planar_ref),
141                                                      GPU_R11F_G11F_B10F,
142                                                      DRW_TEX_FILTER | DRW_TEX_MIPMAP,
143                                                      NULL);
144       txl->planar_depth = DRW_texture_create_2d_array(
145           width, height, max_ii(1, num_planar_ref), GPU_DEPTH_COMPONENT24, 0, NULL);
146     }
147     else if (num_planar_ref == 0) {
148       /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still
149        * bound to shader. */
150       txl->planar_pool = DRW_texture_create_2d_array(
151           1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
152       txl->planar_depth = DRW_texture_create_2d_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL);
153     }
154   }
155 }
156
157 void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
158 {
159   EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
160   EEVEE_StorageList *stl = vedata->stl;
161
162   const DRWContextState *draw_ctx = DRW_context_state_get();
163   const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
164
165   if (!e_data.hammersley) {
166     EEVEE_shaders_lightprobe_shaders_init();
167     e_data.hammersley = create_hammersley_sample_texture(HAMMERSLEY_SIZE);
168   }
169
170   memset(stl->g_data->bake_views, 0, sizeof(stl->g_data->bake_views));
171   memset(stl->g_data->cube_views, 0, sizeof(stl->g_data->cube_views));
172   memset(stl->g_data->world_views, 0, sizeof(stl->g_data->world_views));
173   memset(stl->g_data->planar_views, 0, sizeof(stl->g_data->planar_views));
174
175   /* Use fallback if we don't have gpu texture allocated an we cannot restore them. */
176   bool use_fallback_lightcache = (scene_eval->eevee.light_cache == NULL) ||
177                                  ((scene_eval->eevee.light_cache->grid_tx.tex == NULL) &&
178                                   (scene_eval->eevee.light_cache->grid_tx.data == NULL)) ||
179                                  ((scene_eval->eevee.light_cache->cube_tx.tex == NULL) &&
180                                   (scene_eval->eevee.light_cache->cube_tx.data == NULL));
181
182   if (use_fallback_lightcache && (sldata->fallback_lightcache == NULL)) {
183 #if defined(IRRADIANCE_SH_L2)
184     int grid_res = 4;
185 #elif defined(IRRADIANCE_CUBEMAP)
186     int grid_res = 8;
187 #elif defined(IRRADIANCE_HL2)
188     int grid_res = 4;
189 #endif
190     int cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(scene_eval->eevee.gi_cubemap_resolution);
191     int vis_res = scene_eval->eevee.gi_visibility_resolution;
192     sldata->fallback_lightcache = EEVEE_lightcache_create(
193         1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1});
194   }
195
196   stl->g_data->light_cache = (use_fallback_lightcache) ? sldata->fallback_lightcache :
197                                                          scene_eval->eevee.light_cache;
198
199   EEVEE_lightcache_load(stl->g_data->light_cache);
200
201   if (!sldata->probes) {
202     sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo");
203     sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL);
204     sldata->grid_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightGrid) * MAX_GRID, NULL);
205     sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR,
206                                                   NULL);
207   }
208
209   common_data->prb_num_planar = 0;
210   common_data->prb_num_render_cube = 1;
211   common_data->prb_num_render_grid = 1;
212
213   common_data->spec_toggle = true;
214   common_data->ssr_toggle = true;
215   common_data->ssrefract_toggle = true;
216   common_data->sss_toggle = true;
217
218   /* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */
219   if (!e_data.planar_pool_placeholder) {
220     e_data.planar_pool_placeholder = DRW_texture_create_2d_array(
221         1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER, NULL);
222   }
223 }
224
225 /* Only init the passes useful for rendering the light cache. */
226 void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
227                                 EEVEE_Data *vedata,
228                                 GPUTexture *rt_color,
229                                 GPUTexture *rt_depth)
230 {
231   EEVEE_PassList *psl = vedata->psl;
232   LightCache *light_cache = vedata->stl->g_data->light_cache;
233   EEVEE_LightProbesInfo *pinfo = sldata->probes;
234
235   {
236     DRW_PASS_CREATE(psl->probe_glossy_compute, DRW_STATE_WRITE_COLOR);
237
238     DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_filter_glossy_sh_get(),
239                                               psl->probe_glossy_compute);
240
241     DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
242     DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1);
243     DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1);
244     DRW_shgroup_uniform_float(grp, "roughnessSquared", &pinfo->roughness, 1);
245     DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1);
246     DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1);
247     DRW_shgroup_uniform_float(grp, "texelSize", &pinfo->texel_size, 1);
248     DRW_shgroup_uniform_float(grp, "paddingSize", &pinfo->padding_size, 1);
249     DRW_shgroup_uniform_float(grp, "fireflyFactor", &pinfo->firefly_fac, 1);
250     DRW_shgroup_uniform_int(grp, "Layer", &pinfo->layer, 1);
251     DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
252     // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
253     DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
254     DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
255
256     struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
257     DRW_shgroup_call(grp, geom, NULL);
258   }
259
260   {
261     DRW_PASS_CREATE(psl->probe_diffuse_compute, DRW_STATE_WRITE_COLOR);
262     DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_filter_diffuse_sh_get(),
263                                               psl->probe_diffuse_compute);
264 #ifdef IRRADIANCE_SH_L2
265     DRW_shgroup_uniform_int(grp, "probeSize", &pinfo->shres, 1);
266 #else
267     DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1);
268     DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1);
269     DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1);
270     DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1);
271     DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
272 #endif
273     DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
274     DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
275     DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
276
277     struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
278     DRW_shgroup_call(grp, geom, NULL);
279   }
280
281   {
282     DRW_PASS_CREATE(psl->probe_visibility_compute, DRW_STATE_WRITE_COLOR);
283     DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_filter_visibility_sh_get(),
284                                               psl->probe_visibility_compute);
285     DRW_shgroup_uniform_int(grp, "outputSize", &pinfo->shres, 1);
286     DRW_shgroup_uniform_float(grp, "visibilityRange", &pinfo->visibility_range, 1);
287     DRW_shgroup_uniform_float(grp, "visibilityBlur", &pinfo->visibility_blur, 1);
288     DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1);
289     DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1);
290     DRW_shgroup_uniform_float(grp, "storedTexelSize", &pinfo->texel_size, 1);
291     DRW_shgroup_uniform_float(grp, "nearClip", &pinfo->near_clip, 1);
292     DRW_shgroup_uniform_float(grp, "farClip", &pinfo->far_clip, 1);
293     DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
294     DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth);
295     DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
296
297     struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
298     DRW_shgroup_call(grp, geom, NULL);
299   }
300
301   {
302     DRW_PASS_CREATE(psl->probe_grid_fill, DRW_STATE_WRITE_COLOR);
303
304     DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_grid_fill_sh_get(),
305                                               psl->probe_grid_fill);
306
307     DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &light_cache->grid_tx.tex);
308
309     struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
310     DRW_shgroup_call(grp, geom, NULL);
311   }
312 }
313
314 void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
315 {
316   EEVEE_TextureList *txl = vedata->txl;
317   EEVEE_PassList *psl = vedata->psl;
318   EEVEE_StorageList *stl = vedata->stl;
319   EEVEE_LightProbesInfo *pinfo = sldata->probes;
320   LightCache *lcache = stl->g_data->light_cache;
321   const DRWContextState *draw_ctx = DRW_context_state_get();
322   const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
323
324   pinfo->num_planar = 0;
325   pinfo->vis_data.collection = NULL;
326   pinfo->do_grid_update = false;
327   pinfo->do_cube_update = false;
328
329   {
330     DRW_PASS_CREATE(psl->probe_background, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
331
332     struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
333     DRWShadingGroup *grp = NULL;
334
335     Scene *scene = draw_ctx->scene;
336     World *wo = scene->world;
337
338     const float *col = G_draw.block.colorBackground;
339
340     /* LookDev */
341     EEVEE_lookdev_cache_init(vedata, &grp, psl->probe_background, 1.0f, wo, pinfo);
342     /* END */
343     if (!grp && wo) {
344       col = &wo->horr;
345
346       if (wo->use_nodes && wo->nodetree) {
347         static float error_col[3] = {1.0f, 0.0f, 1.0f};
348         static float queue_col[3] = {0.5f, 0.5f, 0.5f};
349         struct GPUMaterial *gpumat = EEVEE_material_world_lightprobe_get(scene, wo);
350
351         eGPUMaterialStatus status = GPU_material_status(gpumat);
352
353         switch (status) {
354           case GPU_MAT_SUCCESS:
355             grp = DRW_shgroup_material_create(gpumat, psl->probe_background);
356             DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
357             /* TODO (fclem): remove those (need to clean the GLSL files). */
358             DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
359             DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
360             DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
361             DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
362             DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
363             DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
364             DRW_shgroup_call(grp, geom, NULL);
365             break;
366           case GPU_MAT_QUEUED:
367             stl->g_data->queued_shaders_count++;
368             col = queue_col;
369             break;
370           default:
371             col = error_col;
372             break;
373         }
374       }
375     }
376
377     /* Fallback if shader fails or if not using nodetree. */
378     if (grp == NULL) {
379       grp = DRW_shgroup_create(EEVEE_shaders_probe_default_sh_get(), psl->probe_background);
380       DRW_shgroup_uniform_vec3(grp, "color", col, 1);
381       DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
382       DRW_shgroup_call(grp, geom, NULL);
383     }
384   }
385
386   if (DRW_state_draw_support() && !LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) {
387     DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
388                      DRW_STATE_CULL_BACK;
389     DRW_PASS_CREATE(psl->probe_display, state);
390
391     /* Cube Display */
392     if (scene_eval->eevee.flag & SCE_EEVEE_SHOW_CUBEMAPS && lcache->cube_len > 1) {
393       int cube_len = lcache->cube_len - 1; /* don't count the world. */
394       DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_cube_display_sh_get(),
395                                                 psl->probe_display);
396
397       DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex);
398       DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
399       DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
400       DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
401       DRW_shgroup_uniform_float_copy(
402           grp, "sphere_size", scene_eval->eevee.gi_cubemap_draw_size * 0.5f);
403       /* TODO (fclem) get rid of those UBO. */
404       DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
405       DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
406
407       DRW_shgroup_call_procedural_triangles(grp, NULL, cube_len * 2);
408     }
409
410     /* Grid Display */
411     if (scene_eval->eevee.flag & SCE_EEVEE_SHOW_IRRADIANCE) {
412       EEVEE_LightGrid *egrid = lcache->grid_data + 1;
413       for (int p = 1; p < lcache->grid_len; ++p, egrid++) {
414         DRWShadingGroup *shgrp = DRW_shgroup_create(EEVEE_shaders_probe_grid_display_sh_get(),
415                                                     psl->probe_display);
416
417         DRW_shgroup_uniform_int(shgrp, "offset", &egrid->offset, 1);
418         DRW_shgroup_uniform_ivec3(shgrp, "grid_resolution", egrid->resolution, 1);
419         DRW_shgroup_uniform_vec3(shgrp, "corner", egrid->corner, 1);
420         DRW_shgroup_uniform_vec3(shgrp, "increment_x", egrid->increment_x, 1);
421         DRW_shgroup_uniform_vec3(shgrp, "increment_y", egrid->increment_y, 1);
422         DRW_shgroup_uniform_vec3(shgrp, "increment_z", egrid->increment_z, 1);
423         DRW_shgroup_uniform_vec3(shgrp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
424         DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex);
425         DRW_shgroup_uniform_float_copy(
426             shgrp, "sphere_size", scene_eval->eevee.gi_irradiance_draw_size * 0.5f);
427         /* TODO (fclem) get rid of those UBO. */
428         DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
429         DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
430         DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
431         DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
432         int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2;
433         DRW_shgroup_call_procedural_triangles(shgrp, NULL, tri_count);
434       }
435     }
436
437     /* Planar Display */
438     DRW_shgroup_instance_format(e_data.format_probe_display_planar,
439                                 {
440                                     {"probe_id", DRW_ATTR_INT, 1},
441                                     {"probe_mat", DRW_ATTR_FLOAT, 16},
442                                 });
443
444     DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_display_sh_get(),
445                                               psl->probe_display);
446     DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool);
447
448     stl->g_data->planar_display_shgrp = DRW_shgroup_call_buffer_instance(
449         grp, e_data.format_probe_display_planar, DRW_cache_quad_get());
450   }
451   else {
452     stl->g_data->planar_display_shgrp = NULL;
453   }
454 }
455
456 static bool eevee_lightprobes_culling_test(Object *ob)
457 {
458   LightProbe *probe = (LightProbe *)ob->data;
459
460   switch (probe->type) {
461     case LIGHTPROBE_TYPE_PLANAR: {
462       /* See if this planar probe is inside the view frustum. If not, no need to update it. */
463       /* NOTE: this could be bypassed if we want feedback loop mirrors for rendering. */
464       BoundBox bbox;
465       float tmp[4][4];
466       const float min[3] = {-1.0f, -1.0f, -1.0f};
467       const float max[3] = {1.0f, 1.0f, 1.0f};
468       BKE_boundbox_init_from_minmax(&bbox, min, max);
469
470       copy_m4_m4(tmp, ob->obmat);
471       normalize_v3(tmp[2]);
472       mul_v3_fl(tmp[2], probe->distinf);
473
474       for (int v = 0; v < 8; ++v) {
475         mul_m4_v3(tmp, bbox.vec[v]);
476       }
477       const DRWView *default_view = DRW_view_default_get();
478       return DRW_culling_box_test(default_view, &bbox);
479     }
480     case LIGHTPROBE_TYPE_CUBE:
481       return true; /* TODO */
482     case LIGHTPROBE_TYPE_GRID:
483       return true; /* TODO */
484   }
485   BLI_assert(0);
486   return true;
487 }
488
489 void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *ob)
490 {
491   EEVEE_LightProbesInfo *pinfo = sldata->probes;
492   LightProbe *probe = (LightProbe *)ob->data;
493
494   if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) ||
495       (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE) ||
496       (probe->type == LIGHTPROBE_TYPE_PLANAR && pinfo->num_planar >= MAX_PLANAR)) {
497     printf("Too many probes in the view !!!\n");
498     return;
499   }
500
501   if (probe->type == LIGHTPROBE_TYPE_PLANAR) {
502     /* TODO(fclem): Culling should be done after cache generation.
503      * This is needed for future draw cache persistence. */
504     if (!eevee_lightprobes_culling_test(ob)) {
505       return; /* Culled */
506     }
507     EEVEE_lightprobes_planar_data_from_object(
508         ob, &pinfo->planar_data[pinfo->num_planar], &pinfo->planar_vis_tests[pinfo->num_planar]);
509     /* Debug Display */
510     DRWCallBuffer *grp = vedata->stl->g_data->planar_display_shgrp;
511     if (grp && (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA)) {
512       DRW_buffer_add_entry(grp, &pinfo->num_planar, ob->obmat);
513     }
514
515     pinfo->num_planar++;
516   }
517   else {
518     EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob);
519     if (ped->need_update) {
520       if (probe->type == LIGHTPROBE_TYPE_GRID) {
521         pinfo->do_grid_update = true;
522       }
523       else {
524         pinfo->do_cube_update = true;
525       }
526       ped->need_update = false;
527     }
528   }
529 }
530
531 void EEVEE_lightprobes_grid_data_from_object(Object *ob, EEVEE_LightGrid *egrid, int *offset)
532 {
533   LightProbe *probe = (LightProbe *)ob->data;
534
535   copy_v3_v3_int(egrid->resolution, &probe->grid_resolution_x);
536
537   /* Save current offset and advance it for the next grid. */
538   egrid->offset = *offset;
539   *offset += egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2];
540
541   /* Add one for level 0 */
542   float fac = 1.0f / max_ff(1e-8f, probe->falloff);
543   egrid->attenuation_scale = fac / max_ff(1e-8f, probe->distinf);
544   egrid->attenuation_bias = fac;
545
546   /* Update transforms */
547   float cell_dim[3], half_cell_dim[3];
548   cell_dim[0] = 2.0f / egrid->resolution[0];
549   cell_dim[1] = 2.0f / egrid->resolution[1];
550   cell_dim[2] = 2.0f / egrid->resolution[2];
551
552   mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f);
553
554   /* Matrix converting world space to cell ranges. */
555   invert_m4_m4(egrid->mat, ob->obmat);
556
557   /* First cell. */
558   copy_v3_fl(egrid->corner, -1.0f);
559   add_v3_v3(egrid->corner, half_cell_dim);
560   mul_m4_v3(ob->obmat, egrid->corner);
561
562   /* Opposite neighbor cell. */
563   copy_v3_fl3(egrid->increment_x, cell_dim[0], 0.0f, 0.0f);
564   add_v3_v3(egrid->increment_x, half_cell_dim);
565   add_v3_fl(egrid->increment_x, -1.0f);
566   mul_m4_v3(ob->obmat, egrid->increment_x);
567   sub_v3_v3(egrid->increment_x, egrid->corner);
568
569   copy_v3_fl3(egrid->increment_y, 0.0f, cell_dim[1], 0.0f);
570   add_v3_v3(egrid->increment_y, half_cell_dim);
571   add_v3_fl(egrid->increment_y, -1.0f);
572   mul_m4_v3(ob->obmat, egrid->increment_y);
573   sub_v3_v3(egrid->increment_y, egrid->corner);
574
575   copy_v3_fl3(egrid->increment_z, 0.0f, 0.0f, cell_dim[2]);
576   add_v3_v3(egrid->increment_z, half_cell_dim);
577   add_v3_fl(egrid->increment_z, -1.0f);
578   mul_m4_v3(ob->obmat, egrid->increment_z);
579   sub_v3_v3(egrid->increment_z, egrid->corner);
580
581   /* Visibility bias */
582   egrid->visibility_bias = 0.05f * probe->vis_bias;
583   egrid->visibility_bleed = probe->vis_bleedbias;
584   egrid->visibility_range = 1.0f + sqrtf(max_fff(len_squared_v3(egrid->increment_x),
585                                                  len_squared_v3(egrid->increment_y),
586                                                  len_squared_v3(egrid->increment_z)));
587 }
588
589 void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *eprobe)
590 {
591   LightProbe *probe = (LightProbe *)ob->data;
592
593   /* Update transforms */
594   copy_v3_v3(eprobe->position, ob->obmat[3]);
595
596   /* Attenuation */
597   eprobe->attenuation_type = probe->attenuation_type;
598   eprobe->attenuation_fac = 1.0f / max_ff(1e-8f, probe->falloff);
599
600   unit_m4(eprobe->attenuationmat);
601   scale_m4_fl(eprobe->attenuationmat, probe->distinf);
602   mul_m4_m4m4(eprobe->attenuationmat, ob->obmat, eprobe->attenuationmat);
603   invert_m4(eprobe->attenuationmat);
604
605   /* Parallax */
606   unit_m4(eprobe->parallaxmat);
607
608   if ((probe->flag & LIGHTPROBE_FLAG_CUSTOM_PARALLAX) != 0) {
609     eprobe->parallax_type = probe->parallax_type;
610     scale_m4_fl(eprobe->parallaxmat, probe->distpar);
611   }
612   else {
613     eprobe->parallax_type = probe->attenuation_type;
614     scale_m4_fl(eprobe->parallaxmat, probe->distinf);
615   }
616
617   mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat);
618   invert_m4(eprobe->parallaxmat);
619 }
620
621 void EEVEE_lightprobes_planar_data_from_object(Object *ob,
622                                                EEVEE_PlanarReflection *eplanar,
623                                                EEVEE_LightProbeVisTest *vis_test)
624 {
625   LightProbe *probe = (LightProbe *)ob->data;
626   float normat[4][4], imat[4][4];
627
628   vis_test->collection = probe->visibility_grp;
629   vis_test->invert = probe->flag & LIGHTPROBE_FLAG_INVERT_GROUP;
630   vis_test->cached = false;
631
632   /* Computing mtx : matrix that mirror position around object's XY plane. */
633   normalize_m4_m4(normat, ob->obmat); /* object > world */
634   invert_m4_m4(imat, normat);         /* world > object */
635   /* XY reflection plane */
636   imat[0][2] = -imat[0][2];
637   imat[1][2] = -imat[1][2];
638   imat[2][2] = -imat[2][2];
639   imat[3][2] = -imat[3][2];                /* world > object > mirrored obj */
640   mul_m4_m4m4(eplanar->mtx, normat, imat); /* world > object > mirrored obj > world */
641
642   /* Compute clip plane equation / normal. */
643   copy_v3_v3(eplanar->plane_equation, ob->obmat[2]);
644   normalize_v3(eplanar->plane_equation); /* plane normal */
645   eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->obmat[3]);
646   eplanar->clipsta = probe->clipsta;
647
648   /* Compute XY clip planes. */
649   normalize_v3_v3(eplanar->clip_vec_x, ob->obmat[0]);
650   normalize_v3_v3(eplanar->clip_vec_y, ob->obmat[1]);
651
652   float vec[3] = {0.0f, 0.0f, 0.0f};
653   vec[0] = 1.0f;
654   vec[1] = 0.0f;
655   vec[2] = 0.0f;
656   mul_m4_v3(ob->obmat, vec); /* Point on the edge */
657   eplanar->clip_edge_x_pos = dot_v3v3(eplanar->clip_vec_x, vec);
658
659   vec[0] = 0.0f;
660   vec[1] = 1.0f;
661   vec[2] = 0.0f;
662   mul_m4_v3(ob->obmat, vec); /* Point on the edge */
663   eplanar->clip_edge_y_pos = dot_v3v3(eplanar->clip_vec_y, vec);
664
665   vec[0] = -1.0f;
666   vec[1] = 0.0f;
667   vec[2] = 0.0f;
668   mul_m4_v3(ob->obmat, vec); /* Point on the edge */
669   eplanar->clip_edge_x_neg = dot_v3v3(eplanar->clip_vec_x, vec);
670
671   vec[0] = 0.0f;
672   vec[1] = -1.0f;
673   vec[2] = 0.0f;
674   mul_m4_v3(ob->obmat, vec); /* Point on the edge */
675   eplanar->clip_edge_y_neg = dot_v3v3(eplanar->clip_vec_y, vec);
676
677   /* Facing factors */
678   float max_angle = max_ff(1e-2f, 1.0f - probe->falloff) * M_PI * 0.5f;
679   float min_angle = 0.0f;
680   eplanar->facing_scale = 1.0f / max_ff(1e-8f, cosf(min_angle) - cosf(max_angle));
681   eplanar->facing_bias = -min_ff(1.0f - 1e-8f, cosf(max_angle)) * eplanar->facing_scale;
682
683   /* Distance factors */
684   float max_dist = probe->distinf;
685   float min_dist = min_ff(1.0f - 1e-8f, 1.0f - probe->falloff) * probe->distinf;
686   eplanar->attenuation_scale = -1.0f / max_ff(1e-8f, max_dist - min_dist);
687   eplanar->attenuation_bias = max_dist * -eplanar->attenuation_scale;
688 }
689
690 static void lightbake_planar_ensure_view(EEVEE_PlanarReflection *eplanar,
691                                          const DRWView *main_view,
692                                          DRWView **r_planar_view)
693 {
694   float winmat[4][4], viewmat[4][4];
695   DRW_view_viewmat_get(main_view, viewmat, false);
696   /* Temporal sampling jitter should be already applied to the DRW_MAT_WIN. */
697   DRW_view_winmat_get(main_view, winmat, false);
698   /* Invert X to avoid flipping the triangle facing direction. */
699   winmat[0][0] = -winmat[0][0];
700   winmat[1][0] = -winmat[1][0];
701   winmat[2][0] = -winmat[2][0];
702   winmat[3][0] = -winmat[3][0];
703   /* Reflect Camera Matrix. */
704   mul_m4_m4m4(viewmat, viewmat, eplanar->mtx);
705
706   if (*r_planar_view == NULL) {
707     *r_planar_view = DRW_view_create(
708         viewmat, winmat, NULL, NULL, EEVEE_lightprobes_obj_visibility_cb);
709     /* Compute offset plane equation (fix missing texels near reflection plane). */
710     float clip_plane[4];
711     copy_v4_v4(clip_plane, eplanar->plane_equation);
712     clip_plane[3] += eplanar->clipsta;
713     /* Set clipping plane */
714     DRW_view_clip_planes_set(*r_planar_view, &clip_plane, 1);
715   }
716   else {
717     DRW_view_update(*r_planar_view, viewmat, winmat, NULL, NULL);
718   }
719 }
720
721 static void eevee_lightprobes_extract_from_cache(EEVEE_LightProbesInfo *pinfo, LightCache *lcache)
722 {
723   /* copy the entire cache for now (up to MAX_PROBE) */
724   /* TODO Frutum cull to only add visible probes. */
725   memcpy(pinfo->probe_data,
726          lcache->cube_data,
727          sizeof(EEVEE_LightProbe) * max_ii(1, min_ii(lcache->cube_len, MAX_PROBE)));
728   /* TODO compute the max number of grid based on sample count. */
729   memcpy(pinfo->grid_data,
730          lcache->grid_data,
731          sizeof(EEVEE_LightGrid) * max_ii(1, min_ii(lcache->grid_len, MAX_GRID)));
732 }
733
734 void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
735 {
736   EEVEE_StorageList *stl = vedata->stl;
737   LightCache *light_cache = stl->g_data->light_cache;
738   EEVEE_LightProbesInfo *pinfo = sldata->probes;
739   const DRWContextState *draw_ctx = DRW_context_state_get();
740   const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
741
742   eevee_lightprobes_extract_from_cache(sldata->probes, light_cache);
743
744   DRW_uniformbuffer_update(sldata->probe_ubo, &sldata->probes->probe_data);
745   DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data);
746
747   /* For shading, save max level of the octahedron map */
748   sldata->common_data.prb_lod_cube_max = (float)light_cache->mips_len - 1.0f;
749   sldata->common_data.prb_lod_planar_max = (float)MAX_PLANAR_LOD_LEVEL;
750   sldata->common_data.prb_irradiance_vis_size = light_cache->vis_res;
751   sldata->common_data.prb_irradiance_smooth = SQUARE(scene_eval->eevee.gi_irradiance_smoothing);
752   sldata->common_data.prb_num_render_cube = max_ii(1, light_cache->cube_len);
753   sldata->common_data.prb_num_render_grid = max_ii(1, light_cache->grid_len);
754   sldata->common_data.prb_num_planar = pinfo->num_planar;
755
756   if (pinfo->num_planar != pinfo->cache_num_planar) {
757     DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_pool);
758     DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_depth);
759     pinfo->cache_num_planar = pinfo->num_planar;
760   }
761   planar_pool_ensure_alloc(vedata, pinfo->num_planar);
762
763   /* If light-cache auto-update is enable we tag the relevant part
764    * of the cache to update and fire up a baking job. */
765   if (!DRW_state_is_image_render() && !DRW_state_is_opengl_render() &&
766       (pinfo->do_grid_update || pinfo->do_cube_update)) {
767     BLI_assert(draw_ctx->evil_C);
768
769     if (draw_ctx->scene->eevee.flag & SCE_EEVEE_GI_AUTOBAKE) {
770       Scene *scene_orig = DEG_get_input_scene(draw_ctx->depsgraph);
771       if (scene_orig->eevee.light_cache != NULL) {
772         if (pinfo->do_grid_update) {
773           scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID;
774         }
775         /* If we update grid we need to update the cubemaps too.
776          * So always refresh cubemaps. */
777         scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
778         /* Tag the lightcache to auto update. */
779         scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_AUTO;
780         /* Use a notifier to trigger the operator after drawing. */
781         WM_event_add_notifier(draw_ctx->evil_C, NC_LIGHTPROBE, scene_orig);
782       }
783     }
784   }
785
786   if (pinfo->num_planar > 0) {
787     EEVEE_PassList *psl = vedata->psl;
788     EEVEE_TextureList *txl = vedata->txl;
789     DRW_PASS_CREATE(psl->probe_planar_downsample_ps, DRW_STATE_WRITE_COLOR);
790
791     DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_downsample_sh_get(),
792                                               psl->probe_planar_downsample_ps);
793
794     DRW_shgroup_uniform_texture_ref(grp, "source", &txl->planar_pool);
795     DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1);
796     DRW_shgroup_call_procedural_triangles(grp, NULL, pinfo->num_planar);
797   }
798 }
799
800 /* -------------------------------------------------------------------- */
801 /** \name Rendering
802  * \{ */
803
804 typedef struct EEVEE_BakeRenderData {
805   EEVEE_Data *vedata;
806   EEVEE_ViewLayerData *sldata;
807   struct GPUFrameBuffer **face_fb; /* should contain 6 framebuffer */
808 } EEVEE_BakeRenderData;
809
810 static void render_cubemap(void (*callback)(int face, EEVEE_BakeRenderData *user_data),
811                            EEVEE_BakeRenderData *user_data,
812                            const float pos[3],
813                            float near,
814                            float far,
815                            bool do_culling)
816 {
817   EEVEE_StorageList *stl = user_data->vedata->stl;
818   DRWView **views = do_culling ? stl->g_data->bake_views : stl->g_data->world_views;
819
820   float winmat[4][4], viewmat[4][4];
821   perspective_m4(winmat, -near, near, -near, near, near, far);
822
823   /* Prepare views at the same time for faster culling. */
824   for (int i = 0; i < 6; i++) {
825     unit_m4(viewmat);
826     negate_v3_v3(viewmat[3], pos);
827     mul_m4_m4m4(viewmat, cubefacemat[i], viewmat);
828
829     if (do_culling) {
830       if (views[i] == NULL) {
831         views[i] = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
832       }
833       else {
834         DRW_view_update(views[i], viewmat, winmat, NULL, NULL);
835       }
836     }
837     else {
838       if (views[i] == NULL) {
839         const DRWView *default_view = DRW_view_default_get();
840         views[i] = DRW_view_create_sub(default_view, viewmat, winmat);
841       }
842       else {
843         DRW_view_update_sub(views[i], viewmat, winmat);
844       }
845     }
846   }
847
848   for (int i = 0; i < 6; ++i) {
849     DRW_view_set_active(views[i]);
850     callback(i, user_data);
851   }
852 }
853
854 static void render_reflections(void (*callback)(int face, EEVEE_BakeRenderData *user_data),
855                                EEVEE_BakeRenderData *user_data,
856                                EEVEE_PlanarReflection *planar_data,
857                                int ref_count)
858 {
859   EEVEE_StorageList *stl = user_data->vedata->stl;
860   DRWView *main_view = stl->effects->taa_view;
861   DRWView **views = stl->g_data->planar_views;
862   /* Prepare views at the same time for faster culling. */
863   for (int i = 0; i < ref_count; ++i) {
864     lightbake_planar_ensure_view(&planar_data[i], main_view, &views[i]);
865   }
866
867   for (int i = 0; i < ref_count; ++i) {
868     DRW_view_set_active(views[i]);
869     callback(i, user_data);
870   }
871 }
872
873 static void lightbake_render_world_face(int face, EEVEE_BakeRenderData *user_data)
874 {
875   EEVEE_PassList *psl = user_data->vedata->psl;
876   struct GPUFrameBuffer **face_fb = user_data->face_fb;
877
878   /* For world probe, we don't need to clear the color buffer
879    * since we render the background directly. */
880   GPU_framebuffer_bind(face_fb[face]);
881   GPU_framebuffer_clear_depth(face_fb[face], 1.0f);
882   DRW_draw_pass(psl->probe_background);
883 }
884
885 void EEVEE_lightbake_render_world(EEVEE_ViewLayerData *UNUSED(sldata),
886                                   EEVEE_Data *vedata,
887                                   struct GPUFrameBuffer *face_fb[6])
888 {
889   EEVEE_BakeRenderData brdata = {
890       .vedata = vedata,
891       .face_fb = face_fb,
892   };
893
894   render_cubemap(lightbake_render_world_face, &brdata, (float[3]){0.0f}, 1.0f, 10.0f, false);
895 }
896
897 static void lightbake_render_scene_face(int face, EEVEE_BakeRenderData *user_data)
898 {
899   EEVEE_ViewLayerData *sldata = user_data->sldata;
900   EEVEE_PassList *psl = user_data->vedata->psl;
901   EEVEE_PrivateData *g_data = user_data->vedata->stl->g_data;
902   DRWView **views = g_data->bake_views;
903
904   struct GPUFrameBuffer **face_fb = user_data->face_fb;
905
906   /* Be sure that cascaded shadow maps are updated. */
907   EEVEE_draw_shadows(sldata, user_data->vedata, views[face]);
908
909   GPU_framebuffer_bind(face_fb[face]);
910   GPU_framebuffer_clear_depth(face_fb[face], 1.0f);
911
912   DRW_draw_pass(psl->depth_pass);
913   DRW_draw_pass(psl->depth_pass_cull);
914   DRW_draw_pass(psl->probe_background);
915   DRW_draw_pass(psl->material_pass);
916   DRW_draw_pass(psl->material_pass_cull);
917   DRW_draw_pass(psl->sss_pass); /* Only output standard pass */
918   DRW_draw_pass(psl->sss_pass_cull);
919   EEVEE_draw_default_passes(psl);
920   DRW_draw_pass(psl->transparent_pass);
921 }
922
923 /* Render the scene to the probe_rt texture. */
924 void EEVEE_lightbake_render_scene(EEVEE_ViewLayerData *sldata,
925                                   EEVEE_Data *vedata,
926                                   struct GPUFrameBuffer *face_fb[6],
927                                   const float pos[3],
928                                   float near_clip,
929                                   float far_clip)
930 {
931   EEVEE_BakeRenderData brdata = {
932       .vedata = vedata,
933       .sldata = sldata,
934       .face_fb = face_fb,
935   };
936
937   render_cubemap(lightbake_render_scene_face, &brdata, pos, near_clip, far_clip, true);
938 }
939
940 static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *user_data)
941 {
942   EEVEE_Data *vedata = user_data->vedata;
943   EEVEE_ViewLayerData *sldata = user_data->sldata;
944   EEVEE_PassList *psl = vedata->psl;
945   EEVEE_TextureList *txl = vedata->txl;
946   EEVEE_StorageList *stl = vedata->stl;
947   EEVEE_FramebufferList *fbl = vedata->fbl;
948   EEVEE_LightProbesInfo *pinfo = sldata->probes;
949
950   GPU_framebuffer_ensure_config(&fbl->planarref_fb,
951                                 {GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_depth, layer),
952                                  GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_pool, layer)});
953
954   /* Use visibility info for this planar reflection. */
955   pinfo->vis_data = pinfo->planar_vis_tests[layer];
956
957   /* Avoid using the texture attached to framebuffer when rendering. */
958   /* XXX */
959   GPUTexture *tmp_planar_pool = txl->planar_pool;
960   GPUTexture *tmp_planar_depth = txl->planar_depth;
961   txl->planar_pool = e_data.planar_pool_placeholder;
962   txl->planar_depth = e_data.depth_array_placeholder;
963
964   DRW_stats_group_start("Planar Reflection");
965
966   /* Be sure that cascaded shadow maps are updated. */
967   EEVEE_draw_shadows(sldata, vedata, stl->g_data->planar_views[layer]);
968
969   GPU_framebuffer_bind(fbl->planarref_fb);
970   GPU_framebuffer_clear_depth(fbl->planarref_fb, 1.0);
971
972   float prev_background_alpha = vedata->stl->g_data->background_alpha;
973   vedata->stl->g_data->background_alpha = 1.0f;
974
975   /* Slight modification: we handle refraction as normal
976    * shading and don't do SSRefraction. */
977
978   DRW_draw_pass(psl->depth_pass_clip);
979   DRW_draw_pass(psl->depth_pass_clip_cull);
980   DRW_draw_pass(psl->refract_depth_pass_clip);
981   DRW_draw_pass(psl->refract_depth_pass_clip_cull);
982
983   DRW_draw_pass(psl->probe_background);
984   EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer);
985   EEVEE_occlusion_compute(sldata, vedata, tmp_planar_depth, layer);
986
987   GPU_framebuffer_bind(fbl->planarref_fb);
988
989   /* Shading pass */
990   EEVEE_draw_default_passes(psl);
991   DRW_draw_pass(psl->material_pass);
992   DRW_draw_pass(psl->material_pass_cull);
993   DRW_draw_pass(psl->sss_pass); /* Only output standard pass */
994   DRW_draw_pass(psl->sss_pass_cull);
995   DRW_draw_pass(psl->refract_pass);
996
997   /* Transparent */
998   if (DRW_state_is_image_render()) {
999     /* Do the reordering only for offline because it can be costly. */
1000     DRW_pass_sort_shgroup_z(psl->transparent_pass);
1001   }
1002   DRW_draw_pass(psl->transparent_pass);
1003
1004   DRW_stats_group_end();
1005
1006   /* Restore */
1007   txl->planar_pool = tmp_planar_pool;
1008   txl->planar_depth = tmp_planar_depth;
1009
1010   vedata->stl->g_data->background_alpha = prev_background_alpha;
1011 }
1012
1013 static void eevee_lightbake_render_scene_to_planars(EEVEE_ViewLayerData *sldata,
1014                                                     EEVEE_Data *vedata)
1015 {
1016   EEVEE_BakeRenderData brdata = {
1017       .vedata = vedata,
1018       .sldata = sldata,
1019   };
1020
1021   render_reflections(lightbake_render_scene_reflected,
1022                      &brdata,
1023                      sldata->probes->planar_data,
1024                      sldata->probes->num_planar);
1025 }
1026 /** \} */
1027
1028 /* -------------------------------------------------------------------- */
1029 /** \name Filtering
1030  * \{ */
1031
1032 /* Glossy filter rt_color to light_cache->cube_tx.tex at index probe_idx */
1033 void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata,
1034                                    EEVEE_Data *vedata,
1035                                    struct GPUTexture *rt_color,
1036                                    struct GPUFrameBuffer *fb,
1037                                    int probe_idx,
1038                                    float intensity,
1039                                    int maxlevel,
1040                                    float filter_quality,
1041                                    float firefly_fac)
1042 {
1043   EEVEE_PassList *psl = vedata->psl;
1044   EEVEE_LightProbesInfo *pinfo = sldata->probes;
1045   LightCache *light_cache = vedata->stl->g_data->light_cache;
1046
1047   float target_size = (float)GPU_texture_width(rt_color);
1048
1049   /* Max lod used from the render target probe */
1050   pinfo->lod_rt_max = floorf(log2f(target_size)) - 2.0f;
1051   pinfo->intensity_fac = intensity;
1052
1053   /* Start fresh */
1054   GPU_framebuffer_ensure_config(&fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_NONE});
1055
1056   /* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */
1057   /* Bind next framebuffer to be able to gen. mips for probe_rt. */
1058   EEVEE_downsample_cube_buffer(vedata, rt_color, (int)(pinfo->lod_rt_max));
1059
1060   /* 3 - Render to probe array to the specified layer, do prefiltering. */
1061   int mipsize = GPU_texture_width(light_cache->cube_tx.tex);
1062   for (int i = 0; i < maxlevel + 1; i++) {
1063     float bias = 0.0f;
1064     pinfo->texel_size = 1.0f / (float)mipsize;
1065     pinfo->padding_size = (i == maxlevel) ? 0 : (float)(1 << (maxlevel - i - 1));
1066     pinfo->padding_size *= pinfo->texel_size;
1067     pinfo->layer = probe_idx;
1068     pinfo->roughness = i / (float)maxlevel;
1069     pinfo->roughness *= pinfo->roughness;     /* Disney Roughness */
1070     pinfo->roughness *= pinfo->roughness;     /* Distribute Roughness accros lod more evenly */
1071     CLAMP(pinfo->roughness, 1e-8f, 0.99999f); /* Avoid artifacts */
1072
1073 #if 1 /* Variable Sample count and bias (fast) */
1074     switch (i) {
1075       case 0:
1076         pinfo->samples_len = 1.0f;
1077         bias = -1.0f;
1078         break;
1079       case 1:
1080         pinfo->samples_len = 32.0f;
1081         bias = 1.0f;
1082         break;
1083       case 2:
1084         pinfo->samples_len = 40.0f;
1085         bias = 2.0f;
1086         break;
1087       case 3:
1088         pinfo->samples_len = 64.0f;
1089         bias = 2.0f;
1090         break;
1091       default:
1092         pinfo->samples_len = 128.0f;
1093         bias = 2.0f;
1094         break;
1095     }
1096 #else /* Constant Sample count (slow) */
1097     pinfo->samples_len = 1024.0f;
1098 #endif
1099     /* Cannot go higher than HAMMERSLEY_SIZE */
1100     CLAMP(filter_quality, 1.0f, 8.0f);
1101     pinfo->samples_len *= filter_quality;
1102
1103     pinfo->samples_len_inv = 1.0f / pinfo->samples_len;
1104     pinfo->lodfactor = bias +
1105                        0.5f * log((float)(target_size * target_size) * pinfo->samples_len_inv) /
1106                            log(2);
1107     pinfo->firefly_fac = (firefly_fac > 0.0) ? firefly_fac : 1e16;
1108
1109     GPU_framebuffer_ensure_config(
1110         &fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_MIP(light_cache->cube_tx.tex, i)});
1111     GPU_framebuffer_bind(fb);
1112     GPU_framebuffer_viewport_set(fb, 0, 0, mipsize, mipsize);
1113     DRW_draw_pass(psl->probe_glossy_compute);
1114
1115     mipsize /= 2;
1116     CLAMP_MIN(mipsize, 1);
1117   }
1118 }
1119
1120 /* Diffuse filter rt_color to light_cache->grid_tx.tex at index grid_offset */
1121 void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata,
1122                                     EEVEE_Data *vedata,
1123                                     struct GPUTexture *rt_color,
1124                                     struct GPUFrameBuffer *fb,
1125                                     int grid_offset,
1126                                     float intensity)
1127 {
1128   EEVEE_PassList *psl = vedata->psl;
1129   EEVEE_LightProbesInfo *pinfo = sldata->probes;
1130   LightCache *light_cache = vedata->stl->g_data->light_cache;
1131
1132   float target_size = (float)GPU_texture_width(rt_color);
1133
1134   pinfo->intensity_fac = intensity;
1135
1136   /* find cell position on the virtual 3D texture */
1137   /* NOTE : Keep in sync with load_irradiance_cell() */
1138 #if defined(IRRADIANCE_SH_L2)
1139   int size[2] = {3, 3};
1140 #elif defined(IRRADIANCE_CUBEMAP)
1141   int size[2] = {8, 8};
1142   pinfo->samples_len = 1024.0f;
1143 #elif defined(IRRADIANCE_HL2)
1144   int size[2] = {3, 2};
1145   pinfo->samples_len = 1024.0f;
1146 #endif
1147
1148   int cell_per_row = GPU_texture_width(light_cache->grid_tx.tex) / size[0];
1149   int x = size[0] * (grid_offset % cell_per_row);
1150   int y = size[1] * (grid_offset / cell_per_row);
1151
1152 #ifndef IRRADIANCE_SH_L2
1153   /* Tweaking parameters to balance perf. vs precision */
1154   const float bias = 0.0f;
1155   pinfo->samples_len_inv = 1.0f / pinfo->samples_len;
1156   pinfo->lodfactor = bias + 0.5f *
1157                                 log((float)(target_size * target_size) * pinfo->samples_len_inv) /
1158                                 log(2);
1159   pinfo->lod_rt_max = floorf(log2f(target_size)) - 2.0f;
1160 #else
1161   pinfo->shres = 32;        /* Less texture fetches & reduce branches */
1162   pinfo->lod_rt_max = 2.0f; /* Improve cache reuse */
1163 #endif
1164
1165   /* Start fresh */
1166   GPU_framebuffer_ensure_config(&fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_NONE});
1167
1168   /* 4 - Compute diffuse irradiance */
1169   EEVEE_downsample_cube_buffer(vedata, rt_color, (int)(pinfo->lod_rt_max));
1170
1171   GPU_framebuffer_ensure_config(
1172       &fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(light_cache->grid_tx.tex, 0)});
1173   GPU_framebuffer_bind(fb);
1174   GPU_framebuffer_viewport_set(fb, x, y, size[0], size[1]);
1175   DRW_draw_pass(psl->probe_diffuse_compute);
1176 }
1177
1178 /* Filter rt_depth to light_cache->grid_tx.tex at index grid_offset */
1179 void EEVEE_lightbake_filter_visibility(EEVEE_ViewLayerData *sldata,
1180                                        EEVEE_Data *vedata,
1181                                        struct GPUTexture *UNUSED(rt_depth),
1182                                        struct GPUFrameBuffer *fb,
1183                                        int grid_offset,
1184                                        float clipsta,
1185                                        float clipend,
1186                                        float vis_range,
1187                                        float vis_blur,
1188                                        int vis_size)
1189 {
1190   EEVEE_PassList *psl = vedata->psl;
1191   EEVEE_LightProbesInfo *pinfo = sldata->probes;
1192   LightCache *light_cache = vedata->stl->g_data->light_cache;
1193
1194   pinfo->samples_len = 512.0f; /* TODO refine */
1195   pinfo->samples_len_inv = 1.0f / pinfo->samples_len;
1196   pinfo->shres = vis_size;
1197   pinfo->visibility_range = vis_range;
1198   pinfo->visibility_blur = vis_blur;
1199   pinfo->near_clip = -clipsta;
1200   pinfo->far_clip = -clipend;
1201   pinfo->texel_size = 1.0f / (float)vis_size;
1202
1203   int cell_per_col = GPU_texture_height(light_cache->grid_tx.tex) / vis_size;
1204   int cell_per_row = GPU_texture_width(light_cache->grid_tx.tex) / vis_size;
1205   int x = vis_size * (grid_offset % cell_per_row);
1206   int y = vis_size * ((grid_offset / cell_per_row) % cell_per_col);
1207   int layer = 1 + ((grid_offset / cell_per_row) / cell_per_col);
1208
1209   GPU_framebuffer_ensure_config(
1210       &fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(light_cache->grid_tx.tex, layer)});
1211   GPU_framebuffer_bind(fb);
1212   GPU_framebuffer_viewport_set(fb, x, y, vis_size, vis_size);
1213   DRW_draw_pass(psl->probe_visibility_compute);
1214 }
1215
1216 /* Actually a simple downsampling */
1217 static void downsample_planar(void *vedata, int level)
1218 {
1219   EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
1220   EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
1221
1222   const float *size = DRW_viewport_size_get();
1223   copy_v2_v2(stl->g_data->planar_texel_size, size);
1224   for (int i = 0; i < level - 1; ++i) {
1225     stl->g_data->planar_texel_size[0] /= 2.0f;
1226     stl->g_data->planar_texel_size[1] /= 2.0f;
1227     min_ff(floorf(stl->g_data->planar_texel_size[0]), 1.0f);
1228     min_ff(floorf(stl->g_data->planar_texel_size[1]), 1.0f);
1229   }
1230   invert_v2(stl->g_data->planar_texel_size);
1231
1232   DRW_draw_pass(psl->probe_planar_downsample_ps);
1233 }
1234
1235 static void EEVEE_lightbake_filter_planar(EEVEE_Data *vedata)
1236 {
1237   EEVEE_TextureList *txl = vedata->txl;
1238   EEVEE_FramebufferList *fbl = vedata->fbl;
1239
1240   DRW_stats_group_start("Planar Probe Downsample");
1241
1242   GPU_framebuffer_ensure_config(&fbl->planar_downsample_fb,
1243                                 {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->planar_pool)});
1244
1245   GPU_framebuffer_recursive_downsample(
1246       fbl->planar_downsample_fb, MAX_PLANAR_LOD_LEVEL, &downsample_planar, vedata);
1247   DRW_stats_group_end();
1248 }
1249
1250 /** \} */
1251
1252 void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
1253 {
1254   EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
1255   EEVEE_LightProbesInfo *pinfo = sldata->probes;
1256
1257   if (pinfo->num_planar == 0) {
1258     /* Disable SSR if we cannot read previous frame */
1259     common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
1260     common_data->prb_num_planar = 0;
1261     return;
1262   }
1263
1264   /* Temporary Remove all planar reflections (avoid lag effect). */
1265   common_data->prb_num_planar = 0;
1266   /* Turn off ssr to avoid black specular */
1267   common_data->ssr_toggle = false;
1268   common_data->ssrefract_toggle = false;
1269   common_data->sss_toggle = false;
1270
1271   common_data->ray_type = EEVEE_RAY_GLOSSY;
1272   common_data->ray_depth = 1.0f;
1273   DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
1274
1275   /* Rendering happens here! */
1276   eevee_lightbake_render_scene_to_planars(sldata, vedata);
1277
1278   /* Make sure no additional visibility check runs after this. */
1279   pinfo->vis_data.collection = NULL;
1280
1281   DRW_uniformbuffer_update(sldata->planar_ubo, &sldata->probes->planar_data);
1282
1283   /* Restore */
1284   common_data->prb_num_planar = pinfo->num_planar;
1285   common_data->ssr_toggle = true;
1286   common_data->ssrefract_toggle = true;
1287   common_data->sss_toggle = true;
1288
1289   /* Prefilter for SSR */
1290   if ((vedata->stl->effects->enabled_effects & EFFECT_SSR) != 0) {
1291     EEVEE_lightbake_filter_planar(vedata);
1292   }
1293
1294   if (DRW_state_is_image_render()) {
1295     /* Sort transparents because planar reflections could have re-sorted them. */
1296     DRW_pass_sort_shgroup_z(vedata->psl->transparent_pass);
1297   }
1298
1299   /* Disable SSR if we cannot read previous frame */
1300   common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer;
1301 }
1302
1303 void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
1304 {
1305   const DRWContextState *draw_ctx = DRW_context_state_get();
1306   const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
1307   LightCache *light_cache = vedata->stl->g_data->light_cache;
1308
1309   if ((light_cache->flag & LIGHTCACHE_UPDATE_WORLD) &&
1310       (light_cache->flag & LIGHTCACHE_BAKED) == 0) {
1311     EEVEE_lightbake_update_world_quick(sldata, vedata, scene_eval);
1312   }
1313 }
1314
1315 void EEVEE_lightprobes_free(void)
1316 {
1317   MEM_SAFE_FREE(e_data.format_probe_display_cube);
1318   MEM_SAFE_FREE(e_data.format_probe_display_planar);
1319   DRW_TEXTURE_FREE_SAFE(e_data.hammersley);
1320   DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder);
1321   DRW_TEXTURE_FREE_SAFE(e_data.depth_placeholder);
1322   DRW_TEXTURE_FREE_SAFE(e_data.depth_array_placeholder);
1323 }