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