Blender  V2.93
eevee_lightcache.c
Go to the documentation of this file.
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 
25 #include "DRW_render.h"
26 
27 #include "BKE_global.h"
28 
29 #include "BLI_endian_switch.h"
30 #include "BLI_threads.h"
31 
32 #include "DEG_depsgraph_build.h"
33 #include "DEG_depsgraph_query.h"
34 
35 #include "BKE_object.h"
36 
37 #include "DNA_collection_types.h"
38 #include "DNA_lightprobe_types.h"
39 
40 #include "PIL_time.h"
41 
42 #include "eevee_lightcache.h"
43 #include "eevee_private.h"
44 
45 #include "GPU_capabilities.h"
46 #include "GPU_context.h"
47 
48 #include "WM_api.h"
49 #include "WM_types.h"
50 
51 #include "BLO_read_write.h"
52 
53 #include "wm_window.h"
54 
55 /* Rounded to nearest PowerOfTwo */
56 #if defined(IRRADIANCE_SH_L2)
57 # define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
58 # define IRRADIANCE_SAMPLE_SIZE_Y 4 /* 3 in reality */
59 #elif defined(IRRADIANCE_HL2)
60 # define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
61 # define IRRADIANCE_SAMPLE_SIZE_Y 2
62 #endif
63 
64 #ifdef IRRADIANCE_SH_L2
65 /* we need a signed format for Spherical Harmonics */
66 # define IRRADIANCE_FORMAT GPU_RGBA16F
67 #else
68 # define IRRADIANCE_FORMAT GPU_RGBA8
69 #endif
70 
71 /* OpenGL 3.3 core requirement, can be extended but it's already very big */
72 #define IRRADIANCE_MAX_POOL_LAYER 256
73 #define IRRADIANCE_MAX_POOL_SIZE 1024
74 #define MAX_IRRADIANCE_SAMPLES \
75  (IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_X) * \
76  (IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_Y)
77 
78 /* TODO should be replace by a more elegant alternative. */
79 extern void DRW_opengl_context_enable(void);
80 extern void DRW_opengl_context_disable(void);
81 
82 extern void DRW_opengl_render_context_enable(void *re_gl_context);
83 extern void DRW_opengl_render_context_disable(void *re_gl_context);
84 extern void DRW_gpu_render_context_enable(void *re_gpu_context);
85 extern void DRW_gpu_render_context_disable(void *re_gpu_context);
86 
87 typedef struct EEVEE_LightBake {
93  struct Main *bmain;
95 
107  int rt_res;
108 
109  /* Shared */
111  int layer;
115  float lod_factor;
117  float lod_max;
120 
121  /* Irradiance grid */
127  int irr_size[3];
139  float vis_res;
144 
145  /* Reflection probe */
154 
155  /* Dummy Textures */
158 
159  int total, done; /* to compute progress */
160  short *stop, *do_update;
161  float *progress;
162 
169  int delay;
171  int frame;
172 
175 
178 
179 /* -------------------------------------------------------------------- */
183 /* Return memory footprint in bytes. */
185 {
186  uint size = 0;
187  if (lcache->grid_tx.data) {
188  size += MEM_allocN_len(lcache->grid_tx.data);
189  }
190  if (lcache->cube_tx.data) {
191  size += MEM_allocN_len(lcache->cube_tx.data);
192  for (int mip = 0; mip < lcache->mips_len; mip++) {
193  size += MEM_allocN_len(lcache->cube_mips[mip].data);
194  }
195  }
196  return size;
197 }
198 
199 static bool eevee_lightcache_version_check(const LightCache *lcache)
200 {
201  switch (lcache->type) {
203  return lcache->version == LIGHTCACHE_STATIC_VERSION;
204  default:
205  return false;
206  }
207 }
208 
210 {
211  if (lcache->grid_tx.data) {
212  if (MEM_allocN_len(lcache->grid_tx.data) >= INT_MAX) {
213  return false;
214  }
215  }
216  if (lcache->cube_tx.data) {
217  if (MEM_allocN_len(lcache->cube_tx.data) >= INT_MAX) {
218  return false;
219  }
220  }
221  return true;
222 }
223 
225 {
226  int total_irr_samples = 0;
227 
228  for (int i = 1; i < lcache->grid_len; i++) {
229  EEVEE_LightGrid *egrid = lcache->grid_data + i;
230  total_irr_samples += egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2];
231  }
232  return total_irr_samples;
233 }
234 
236 {
237  LightCache *lcache = eevee->light_cache_data;
238 
239  if (lcache != NULL) {
240  if (!eevee_lightcache_version_check(lcache)) {
242  TIP_("Incompatible Light cache version, please bake again"),
243  sizeof(eevee->light_cache_info));
244  return;
245  }
246 
247  if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
249  TIP_("Error: Light cache is too big for the GPU to be loaded"),
250  sizeof(eevee->light_cache_info));
251  return;
252  }
253 
254  if (lcache->flag & LIGHTCACHE_INVALID) {
256  TIP_("Error: Light cache dimensions not supported by the GPU"),
257  sizeof(eevee->light_cache_info));
258  return;
259  }
260 
261  if (lcache->flag & LIGHTCACHE_BAKING) {
262  BLI_strncpy(
263  eevee->light_cache_info, TIP_("Baking light cache"), sizeof(eevee->light_cache_info));
264  return;
265  }
266 
267  if (!eevee_lightcache_can_be_saved(lcache)) {
269  TIP_("Error: LightCache is too large and will not be saved to disk"),
270  sizeof(eevee->light_cache_info));
271  return;
272  }
273 
274  char formatted_mem[15];
275  BLI_str_format_byte_unit(formatted_mem, eevee_lightcache_memsize_get(lcache), false);
276 
277  int irr_samples = eevee_lightcache_irradiance_sample_count(lcache);
278 
280  sizeof(eevee->light_cache_info),
281  TIP_("%d Ref. Cubemaps, %d Irr. Samples (%s in memory)"),
282  lcache->cube_len - 1,
283  irr_samples,
284  formatted_mem);
285  }
286  else {
288  TIP_("No light cache in this scene"),
289  sizeof(eevee->light_cache_info));
290  }
291 }
292 
293 static void irradiance_pool_size_get(int visibility_size, int total_samples, int r_size[3])
294 {
295  /* Compute how many irradiance samples we can store per visibility sample. */
296  int irr_per_vis = (visibility_size / IRRADIANCE_SAMPLE_SIZE_X) *
297  (visibility_size / IRRADIANCE_SAMPLE_SIZE_Y);
298 
299  /* The irradiance itself take one layer, hence the +1 */
300  int layer_ct = MIN2(irr_per_vis + 1, IRRADIANCE_MAX_POOL_LAYER);
301 
302  int texel_ct = (int)ceilf((float)total_samples / (float)(layer_ct - 1));
303  r_size[0] = visibility_size *
304  max_ii(1, min_ii(texel_ct, (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
305  r_size[1] = visibility_size *
306  max_ii(1, (texel_ct / (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
307  r_size[2] = layer_ct;
308 }
309 
310 static bool EEVEE_lightcache_validate(const LightCache *light_cache,
311  const int cube_len,
312  const int cube_res,
313  const int grid_len,
314  const int irr_size[3])
315 {
316  if (light_cache == NULL) {
317  return false;
318  }
319  if (!eevee_lightcache_version_check(light_cache)) {
320  return false;
321  }
322 
323  if (!(light_cache->flag & LIGHTCACHE_INVALID)) {
324  /* See if we need the same amount of texture space. */
325  if ((irr_size[0] == light_cache->grid_tx.tex_size[0]) &&
326  (irr_size[1] == light_cache->grid_tx.tex_size[1]) &&
327  (irr_size[2] == light_cache->grid_tx.tex_size[2]) && (grid_len == light_cache->grid_len)) {
328  int mip_len = log2_floor_u(cube_res) - MIN_CUBE_LOD_LEVEL;
329  if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
330  (cube_len == light_cache->cube_tx.tex_size[2] / 6) &&
331  (cube_len == light_cache->cube_len) && (mip_len == light_cache->mips_len)) {
332  return true;
333  }
334  }
335  }
336  return false;
337 }
338 
340  const int cube_len,
341  const int cube_size,
342  const int vis_size,
343  const int irr_size[3])
344 {
345  LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
346 
347  light_cache->version = LIGHTCACHE_STATIC_VERSION;
348  light_cache->type = LIGHTCACHE_TYPE_STATIC;
349 
350  light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
351  light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
352 
353  light_cache->grid_tx.tex = DRW_texture_create_2d_array(
354  irr_size[0], irr_size[1], irr_size[2], IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
355  light_cache->grid_tx.tex_size[0] = irr_size[0];
356  light_cache->grid_tx.tex_size[1] = irr_size[1];
357  light_cache->grid_tx.tex_size[2] = irr_size[2];
358 
359  int mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
360 
361  /* Try to create a cubemap array. */
364  cube_size, cube_len, GPU_R11F_G11F_B10F, cube_texflag, NULL);
365  if (light_cache->cube_tx.tex == NULL) {
366  /* Try fallback to 2D array. */
367  light_cache->cube_tx.tex = DRW_texture_create_2d_array(
368  cube_size, cube_size, cube_len * 6, GPU_R11F_G11F_B10F, cube_texflag, NULL);
369  }
370 
371  light_cache->cube_tx.tex_size[0] = cube_size;
372  light_cache->cube_tx.tex_size[1] = cube_size;
373  light_cache->cube_tx.tex_size[2] = cube_len * 6;
374 
375  light_cache->mips_len = mips_len;
376  light_cache->vis_res = vis_size;
377  light_cache->ref_res = cube_size;
378 
379  light_cache->cube_mips = MEM_callocN(sizeof(LightCacheTexture) * light_cache->mips_len,
380  "LightCacheTexture");
381 
382  if (light_cache->grid_tx.tex == NULL || light_cache->cube_tx.tex == NULL) {
383  /* We could not create the requested textures size. Stop baking and do not use the cache. */
384  light_cache->flag = LIGHTCACHE_INVALID;
385  }
386  else {
388 
389  for (int mip = 0; mip < light_cache->mips_len; mip++) {
391  light_cache->cube_tx.tex, mip + 1, light_cache->cube_mips[mip].tex_size);
392  }
393  }
394 
395  return light_cache;
396 }
397 
399 {
400  /* We use fallback if a texture is not setup and there is no data to restore it. */
401  if ((!lcache->grid_tx.tex && !lcache->grid_tx.data) || !lcache->grid_data ||
402  (!lcache->cube_tx.tex && !lcache->cube_tx.data) || !lcache->cube_data) {
403  return false;
404  }
405  /* If cache is too big for this GPU. */
406  if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
407  return false;
408  }
409 
410  if (lcache->grid_tx.tex == NULL) {
412  "lightcache_irradiance", UNPACK3(lcache->grid_tx.tex_size), 1, IRRADIANCE_FORMAT, NULL);
414 
415  if (lcache->grid_tx.tex == NULL) {
416  lcache->flag |= LIGHTCACHE_NOT_USABLE;
417  return false;
418  }
419 
420  GPU_texture_filter_mode(lcache->grid_tx.tex, true);
421  }
422 
423  if (lcache->cube_tx.tex == NULL) {
424  /* Try to create a cubemap array. */
425  lcache->cube_tx.tex = GPU_texture_create_cube_array("lightcache_cubemaps",
426  lcache->cube_tx.tex_size[0],
427  lcache->cube_tx.tex_size[2] / 6,
428  lcache->mips_len + 1,
430  NULL);
431 
432  if (lcache->cube_tx.tex == NULL) {
433  /* Try fallback to 2D array. */
434  lcache->cube_tx.tex = GPU_texture_create_2d_array("lightcache_cubemaps_fallback",
435  UNPACK3(lcache->cube_tx.tex_size),
436  lcache->mips_len + 1,
438  NULL);
439  }
440 
441  if (lcache->cube_tx.tex == NULL) {
442  lcache->flag |= LIGHTCACHE_NOT_USABLE;
443  return false;
444  }
445 
446  for (int mip = 0; mip <= lcache->mips_len; mip++) {
447  const void *data = (mip == 0) ? lcache->cube_tx.data : lcache->cube_mips[mip - 1].data;
449  }
450  GPU_texture_mipmap_mode(lcache->cube_tx.tex, true, true);
451  }
452  return true;
453 }
454 
456 {
457  if (lcache == NULL) {
458  return false;
459  }
460 
461  if (!eevee_lightcache_version_check(lcache)) {
462  return false;
463  }
464 
465  if (lcache->flag & (LIGHTCACHE_INVALID | LIGHTCACHE_NOT_USABLE)) {
466  return false;
467  }
468 
469  switch (lcache->type) {
471  return eevee_lightcache_static_load(lcache);
472  default:
473  return false;
474  }
475 }
476 
478 {
479  MEM_SAFE_FREE(lcache->grid_tx.data);
480  lcache->grid_tx.data = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_UBYTE, 0);
482  lcache->grid_tx.components = 4;
483 }
484 
486 {
487  MEM_SAFE_FREE(lcache->cube_tx.data);
490  lcache->cube_tx.components = 1;
491 
492  for (int mip = 0; mip < lcache->mips_len; mip++) {
493  LightCacheTexture *cube_mip = lcache->cube_mips + mip;
494  MEM_SAFE_FREE(cube_mip->data);
495  GPU_texture_get_mipmap_size(lcache->cube_tx.tex, mip + 1, cube_mip->tex_size);
496 
497  cube_mip->data = GPU_texture_read(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1);
498  cube_mip->data_type = LIGHTCACHETEX_UINT;
499  cube_mip->components = 1;
500  }
501 }
502 
504 {
506  MEM_SAFE_FREE(lcache->cube_tx.data);
508  MEM_SAFE_FREE(lcache->grid_tx.data);
509 
510  if (lcache->cube_mips) {
511  for (int i = 0; i < lcache->mips_len; i++) {
512  MEM_SAFE_FREE(lcache->cube_mips[i].data);
513  }
514  MEM_SAFE_FREE(lcache->cube_mips);
515  }
516 
517  MEM_SAFE_FREE(lcache->cube_data);
518  MEM_SAFE_FREE(lcache->grid_data);
519  MEM_freeN(lcache);
520 }
521 
523 {
524  if (tex->data) {
525  size_t data_size = tex->components * tex->tex_size[0] * tex->tex_size[1] * tex->tex_size[2];
526  if (tex->data_type == LIGHTCACHETEX_FLOAT) {
527  data_size *= sizeof(float);
528  }
529  else if (tex->data_type == LIGHTCACHETEX_UINT) {
530  data_size *= sizeof(uint);
531  }
532 
533  /* FIXME: We can't save more than what 32bit systems can handle.
534  * The solution would be to split the texture but it is too late for 2.90. (see T78529) */
535  if (data_size < INT_MAX) {
536  BLO_write_raw(writer, data_size, tex->data);
537  }
538  }
539 }
540 
542 {
543  write_lightcache_texture(writer, &cache->grid_tx);
544  write_lightcache_texture(writer, &cache->cube_tx);
545 
546  if (cache->cube_mips) {
548  for (int i = 0; i < cache->mips_len; i++) {
549  write_lightcache_texture(writer, &cache->cube_mips[i]);
550  }
551  }
552 
553  BLO_write_struct_array(writer, LightGridCache, cache->grid_len, cache->grid_data);
554  BLO_write_struct_array(writer, LightProbeCache, cache->cube_len, cache->cube_data);
555 }
556 
558 {
559  lctex->tex = NULL;
560 
561  if (lctex->data) {
562  BLO_read_data_address(reader, &lctex->data);
563  if (lctex->data && BLO_read_requires_endian_switch(reader)) {
564  int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] *
565  lctex->tex_size[2];
566 
567  if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
568  BLI_endian_switch_float_array((float *)lctex->data, data_size * sizeof(float));
569  }
570  else if (lctex->data_type == LIGHTCACHETEX_UINT) {
571  BLI_endian_switch_uint32_array((uint *)lctex->data, data_size * sizeof(uint));
572  }
573  }
574  }
575 
576  if (lctex->data == NULL) {
577  zero_v3_int(lctex->tex_size);
578  }
579 }
580 
582 {
583  cache->flag &= ~LIGHTCACHE_NOT_USABLE;
584  direct_link_lightcache_texture(reader, &cache->cube_tx);
585  direct_link_lightcache_texture(reader, &cache->grid_tx);
586 
587  if (cache->cube_mips) {
588  BLO_read_data_address(reader, &cache->cube_mips);
589  for (int i = 0; i < cache->mips_len; i++) {
590  direct_link_lightcache_texture(reader, &cache->cube_mips[i]);
591  }
592  }
593 
594  BLO_read_data_address(reader, &cache->cube_data);
595  BLO_read_data_address(reader, &cache->grid_data);
596 }
597 
600 /* -------------------------------------------------------------------- */
605 {
609  return;
610  }
611 
612  if (lbake->gl_context) {
614  if (lbake->gpu_context == NULL) {
616  }
618  }
619  else {
621  }
622 }
623 
625 {
629  return;
630  }
631 
632  if (lbake->gl_context) {
635  }
636  else {
638  }
639 }
640 
643 /* -------------------------------------------------------------------- */
648 {
649  Depsgraph *depsgraph = lbake->depsgraph;
650 
651  /* At least one of each for the world */
652  lbake->grid_len = lbake->cube_len = lbake->total_irr_samples = 1;
653 
655  const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
656  if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
657  continue;
658  }
659 
660  if (ob->type == OB_LIGHTPROBE) {
661  LightProbe *prb = (LightProbe *)ob->data;
662 
663  if (prb->type == LIGHTPROBE_TYPE_GRID) {
665  prb->grid_resolution_z;
666  lbake->grid_len++;
667  }
668  else if (prb->type == LIGHTPROBE_TYPE_CUBE && lbake->cube_len < EEVEE_PROBE_MAX) {
669  lbake->cube_len++;
670  }
671  }
672  }
674 }
675 
677 {
681 
682  for (int i = 0; i < 6; i++) {
683  GPU_framebuffer_ensure_config(&lbake->rt_fb[i],
684  {GPU_ATTACHMENT_TEXTURE_CUBEFACE(lbake->rt_depth, i),
685  GPU_ATTACHMENT_TEXTURE_CUBEFACE(lbake->rt_color, i)});
686  }
687 
688  GPU_framebuffer_ensure_config(&lbake->store_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_NONE});
689 }
690 
692 {
693  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
694  SceneEEVEE *eevee = &scene_eval->eevee;
695 
696  lbake->bounce_len = eevee->gi_diffuse_bounces;
697  lbake->vis_res = eevee->gi_visibility_resolution;
698  lbake->rt_res = eevee->gi_cubemap_resolution;
699 
701 
702  lbake->ref_cube_res = lbake->rt_res;
703  lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
704  lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
705 
707  lbake->irr_size[1],
708  lbake->irr_size[2],
711  NULL);
712 
713  /* Ensure Light Cache is ready to accept new data. If not recreate one.
714  * WARNING: All the following must be threadsafe. It's currently protected
715  * by the DRW mutex. */
716  lbake->lcache = eevee->light_cache_data;
717 
718  /* TODO validate irradiance and reflection cache independently... */
720  lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->grid_len, lbake->irr_size)) {
721  eevee->light_cache_data = lbake->lcache = NULL;
722  }
723 
724  if (lbake->lcache == NULL) {
726  lbake->grid_len, lbake->cube_len, lbake->ref_cube_res, lbake->vis_res, lbake->irr_size);
727 
728  lbake->own_light_cache = true;
729 
730  eevee->light_cache_data = lbake->lcache;
731  }
732 
734 
735  lbake->lcache->flag |= LIGHTCACHE_BAKING;
736  lbake->lcache->cube_len = 1;
737 }
738 
740  struct wmWindow *win,
741  struct Main *bmain,
742  struct ViewLayer *view_layer,
743  struct Scene *scene,
744  int delay,
745  int frame)
746 {
747  EEVEE_LightBake *lbake = NULL;
748 
749  /* only one render job at a time */
751  return NULL;
752  }
753 
754  wmJob *wm_job = WM_jobs_get(wm,
755  win,
756  scene,
757  "Bake Lighting",
760 
761  /* If job exists do not recreate context and depsgraph. */
763 
764  if (old_lbake && (old_lbake->view_layer_input == view_layer) && (old_lbake->bmain == bmain)) {
765  lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
766  /* Cannot reuse depsgraph for now because we cannot get the update from the
767  * main database directly. TODO reuse depsgraph and only update positions. */
768  /* lbake->depsgraph = old_lbake->depsgraph; */
769  lbake->depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
770 
771  lbake->mutex = BLI_mutex_alloc();
772 
773  BLI_mutex_lock(old_lbake->mutex);
774  old_lbake->own_resources = false;
775 
776  lbake->scene = scene;
777  lbake->bmain = bmain;
778  lbake->view_layer_input = view_layer;
779  lbake->gl_context = old_lbake->gl_context;
780  lbake->own_resources = true;
781  lbake->delay = delay;
782  lbake->frame = frame;
783 
784  if (lbake->gl_context == NULL && !GPU_use_main_context_workaround()) {
787  }
788 
789  if (old_lbake->stop != NULL) {
790  *old_lbake->stop = 1;
791  }
792  BLI_mutex_unlock(old_lbake->mutex);
793  }
794  else {
795  lbake = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, true, frame);
796  lbake->delay = delay;
797  }
798 
800  WM_jobs_timer(wm_job, 0.4, NC_SCENE | NA_EDITED, 0);
803 
804  G.is_break = false;
805 
806  return wm_job;
807 }
808 
809 /* MUST run on the main thread. */
811  struct ViewLayer *view_layer,
812  struct Scene *scene,
813  bool run_as_job,
814  int frame)
815 {
817 
818  EEVEE_LightBake *lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
819 
820  lbake->depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
821  lbake->scene = scene;
822  lbake->bmain = bmain;
823  lbake->view_layer_input = view_layer;
824  lbake->own_resources = true;
825  lbake->own_light_cache = false;
826  lbake->mutex = BLI_mutex_alloc();
827  lbake->frame = frame;
828 
829  if (run_as_job && !GPU_use_main_context_workaround()) {
832  }
833 
834  return lbake;
835 }
836 
837 void EEVEE_lightbake_job_data_free(void *custom_data)
838 {
839  EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
840 
841  /* TODO reuse depsgraph. */
842  /* if (lbake->own_resources) { */
843  DEG_graph_free(lbake->depsgraph);
844  /* } */
845 
846  MEM_SAFE_FREE(lbake->cube_prb);
847  MEM_SAFE_FREE(lbake->grid_prb);
848 
849  BLI_mutex_free(lbake->mutex);
850 
851  MEM_freeN(lbake);
852 }
853 
855 {
856  if (!lbake->resource_only) {
857  BLI_mutex_lock(lbake->mutex);
858  }
859 
860  if (lbake->gl_context) {
863  }
864  else if (!lbake->resource_only) {
866  }
867 
868  /* XXX Free the resources contained in the viewlayer data
869  * to be able to free the context before deleting the depsgraph. */
870  if (lbake->sldata) {
872  }
873 
878  for (int i = 0; i < 6; i++) {
879  GPU_FRAMEBUFFER_FREE_SAFE(lbake->rt_fb[i]);
880  }
881 
882  if (lbake->gpu_context) {
886  }
887 
888  if (lbake->gl_context && lbake->own_resources) {
889  /* Delete the baking context. */
892  lbake->gpu_context = NULL;
893  lbake->gl_context = NULL;
894  }
895  else if (lbake->gl_context) {
897  }
898  else if (!lbake->resource_only) {
900  }
901 
902  if (!lbake->resource_only) {
903  BLI_mutex_unlock(lbake->mutex);
904  }
905 }
906 
907 /* Cache as in draw cache not light cache. */
909 {
910  EEVEE_TextureList *txl = vedata->txl;
911  EEVEE_StorageList *stl = vedata->stl;
912  EEVEE_FramebufferList *fbl = vedata->fbl;
914  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
915  lbake->sldata = sldata;
916 
917  /* Disable all effects BUT high bit-depth shadows. */
919  scene_eval->eevee.taa_samples = 1;
920  scene_eval->eevee.gi_irradiance_smoothing = 0.0f;
921 
922  stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
923  stl->g_data->background_alpha = 1.0f;
924  stl->g_data->render_timesteps = 1;
925 
926  /* XXX TODO remove this. This is in order to make the init functions work. */
927  if (DRW_view_default_get() == NULL) {
928  float winmat[4][4], viewmat[4][4];
929  unit_m4(viewmat);
930  unit_m4(winmat);
931  negate_v3(winmat[2]);
932  DRWView *view = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
935  }
936 
937  /* HACK: set txl->color but unset it before Draw Manager frees it. */
938  txl->color = lbake->rt_color;
939  const int viewport_size[2] = {
940  GPU_texture_width(txl->color),
942  };
943  DRW_render_viewport_size_set(viewport_size);
944 
945  EEVEE_effects_init(sldata, vedata, NULL, true);
946  EEVEE_materials_init(sldata, vedata, stl, fbl);
947  EEVEE_shadows_init(sldata);
948  EEVEE_lightprobes_init(sldata, vedata);
949 
950  EEVEE_effects_cache_init(sldata, vedata);
951  EEVEE_materials_cache_init(sldata, vedata);
952  EEVEE_subsurface_cache_init(sldata, vedata);
953  EEVEE_volumes_cache_init(sldata, vedata);
954  EEVEE_lights_cache_init(sldata, vedata);
955  EEVEE_lightprobes_cache_init(sldata, vedata);
956 
957  EEVEE_lightbake_cache_init(sldata, vedata, lbake->rt_color, lbake->rt_depth);
958 
959  if (lbake->probe) {
960  EEVEE_LightProbesInfo *pinfo = sldata->probes;
961  LightProbe *prb = *lbake->probe;
962  pinfo->vis_data.collection = prb->visibility_grp;
964  pinfo->vis_data.cached = false;
965  }
967 
968  EEVEE_volumes_cache_finish(sldata, vedata);
969  EEVEE_materials_cache_finish(sldata, vedata);
970  EEVEE_lights_cache_finish(sldata, vedata);
971  EEVEE_lightprobes_cache_finish(sldata, vedata);
972  EEVEE_shadows_update(sldata, vedata);
973 
974  /* Disable volumetrics when baking. */
976 
977  EEVEE_subsurface_draw_init(sldata, vedata);
978  EEVEE_effects_draw_init(sldata, vedata);
979  EEVEE_volumes_draw_init(sldata, vedata);
980 
981  txl->color = NULL;
982 
984  DRW_hair_update();
985 }
986 
988 {
990 
991  /* Copy texture by reading back and re-uploading it. */
992  float *tex = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_FLOAT, 0);
994  lbake->irr_size[1],
995  lbake->irr_size[2],
998  tex);
999 
1000  MEM_freeN(tex);
1001 }
1002 
1003 static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
1004 {
1005  EEVEE_Data *vedata = (EEVEE_Data *)ved;
1008  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
1009  LightCache *lcache = scene_eval->eevee.light_cache_data;
1010  float clamp = scene_eval->eevee.gi_glossy_clamp;
1011  float filter_quality = scene_eval->eevee.gi_filter_quality;
1012 
1013  /* TODO do this once for the whole bake when we have independent DRWManagers. */
1014  eevee_lightbake_cache_create(vedata, lbake);
1015 
1017  sldata->common_data.ray_depth = 1;
1018  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1019  EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
1021  vedata,
1022  lbake->rt_color,
1023  lbake->store_fb,
1024  0,
1025  1.0f,
1026  lcache->mips_len,
1027  filter_quality,
1028  clamp);
1029 
1031  sldata->common_data.ray_depth = 1;
1032  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1033  EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
1034  EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f);
1035 
1036  if (lcache->flag & LIGHTCACHE_UPDATE_GRID) {
1037  /* Clear the cache to avoid white values in the grid. */
1038  GPU_framebuffer_texture_attach(lbake->store_fb, lbake->grid_prev, 0, 0);
1040  /* Clear to 1.0f for visibility. */
1041  GPU_framebuffer_clear_color(lbake->store_fb, ((float[4]){1.0f, 1.0f, 1.0f, 1.0f}));
1042  DRW_draw_pass(vedata->psl->probe_grid_fill);
1043 
1044  SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
1045 
1046  /* Make a copy for later. */
1047  eevee_lightbake_copy_irradiance(lbake, lcache);
1048  }
1049 
1050  lcache->cube_len = 1;
1051  lcache->grid_len = lbake->grid_len;
1052 
1054  lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
1055 }
1056 
1057 static void cell_id_to_grid_loc(EEVEE_LightGrid *egrid, int cell_idx, int r_local_cell[3])
1058 {
1059  /* Keep in sync with lightprobe_grid_display_vert */
1060  r_local_cell[2] = cell_idx % egrid->resolution[2];
1061  r_local_cell[1] = (cell_idx / egrid->resolution[2]) % egrid->resolution[1];
1062  r_local_cell[0] = cell_idx / (egrid->resolution[2] * egrid->resolution[1]);
1063 }
1064 
1066  LightProbe *probe,
1067  int cell_idx,
1068  int *r_final_idx,
1069  int r_local_cell[3],
1070  int *r_stride)
1071 {
1072  const int cell_count = probe->grid_resolution_x * probe->grid_resolution_y *
1073  probe->grid_resolution_z;
1074 
1075  /* Add one for level 0 */
1076  int max_lvl = (int)floorf(log2f(
1077  (float)MAX3(probe->grid_resolution_x, probe->grid_resolution_y, probe->grid_resolution_z)));
1078 
1079  int visited_cells = 0;
1080  *r_stride = 0;
1081  *r_final_idx = 0;
1082  r_local_cell[0] = r_local_cell[1] = r_local_cell[2] = 0;
1083  for (int lvl = max_lvl; lvl >= 0; lvl--) {
1084  *r_stride = 1 << lvl;
1085  int prev_stride = *r_stride << 1;
1086  for (int i = 0; i < cell_count; i++) {
1087  *r_final_idx = i;
1088  cell_id_to_grid_loc(egrid, *r_final_idx, r_local_cell);
1089  if (((r_local_cell[0] % *r_stride) == 0) && ((r_local_cell[1] % *r_stride) == 0) &&
1090  ((r_local_cell[2] % *r_stride) == 0)) {
1091  if (!(((r_local_cell[0] % prev_stride) == 0) && ((r_local_cell[1] % prev_stride) == 0) &&
1092  ((r_local_cell[2] % prev_stride) == 0)) ||
1093  ((i == 0) && (lvl == max_lvl))) {
1094  if (visited_cells == cell_idx) {
1095  return;
1096  }
1097 
1098  visited_cells++;
1099  }
1100  }
1101  }
1102  }
1103 
1104  BLI_assert(0);
1105 }
1106 
1107 static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, const int local_cell[3], float r_pos[3])
1108 {
1109  copy_v3_v3(r_pos, egrid->corner);
1110  madd_v3_v3fl(r_pos, egrid->increment_x, local_cell[0]);
1111  madd_v3_v3fl(r_pos, egrid->increment_y, local_cell[1]);
1112  madd_v3_v3fl(r_pos, egrid->increment_z, local_cell[2]);
1113 }
1114 
1115 static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
1116 {
1117  EEVEE_Data *vedata = (EEVEE_Data *)ved;
1119  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
1121  EEVEE_LightGrid *egrid = lbake->grid;
1122  LightProbe *prb = *lbake->probe;
1123  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
1124  LightCache *lcache = scene_eval->eevee.light_cache_data;
1125  int grid_loc[3], sample_id, sample_offset, stride;
1126  float pos[3];
1127  const bool is_last_bounce_sample = ((egrid->offset + lbake->grid_sample) ==
1128  (lbake->total_irr_samples - 1));
1129 
1130  /* No bias for rendering the probe. */
1131  egrid->level_bias = 1.0f;
1132 
1133  /* Use the previous bounce for rendering this bounce. */
1134  SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
1135 
1136  /* TODO do this once for the whole bake when we have independent DRWManagers.
1137  * Warning: Some of the things above require this. */
1138  eevee_lightbake_cache_create(vedata, lbake);
1139 
1140  /* Compute sample position */
1141  compute_cell_id(egrid, prb, lbake->grid_sample, &sample_id, grid_loc, &stride);
1142  sample_offset = egrid->offset + sample_id;
1143 
1144  grid_loc_to_world_loc(egrid, grid_loc, pos);
1145 
1146  /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
1147  common_data->spec_toggle = false;
1148  common_data->sss_toggle = false;
1149  common_data->prb_num_planar = 0;
1150  common_data->prb_num_render_cube = 0;
1151  common_data->ray_type = EEVEE_RAY_DIFFUSE;
1152  common_data->ray_depth = lbake->bounce_curr + 1;
1153  if (lbake->bounce_curr == 0) {
1154  common_data->prb_num_render_grid = 0;
1155  }
1156  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1157 
1158  EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, pos, prb->clipsta, prb->clipend);
1159 
1160  /* Restore before filtering. */
1161  SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
1162 
1164  sldata, vedata, lbake->rt_color, lbake->store_fb, sample_offset, prb->intensity);
1165 
1166  if (lbake->bounce_curr == 0) {
1167  /* We only need to filter the visibility for the first bounce. */
1169  vedata,
1170  lbake->rt_depth,
1171  lbake->store_fb,
1172  sample_offset,
1173  prb->clipsta,
1174  prb->clipend,
1175  egrid->visibility_range,
1176  prb->vis_blur,
1177  lbake->vis_res);
1178  }
1179 
1180  /* Update level for progressive update. */
1181  if (is_last_bounce_sample) {
1182  egrid->level_bias = 1.0f;
1183  }
1184  else if (lbake->bounce_curr == 0) {
1185  egrid->level_bias = (float)(stride << 1);
1186  }
1187 
1188  /* Only run this for the last sample of a bounce. */
1189  if (is_last_bounce_sample) {
1190  eevee_lightbake_copy_irradiance(lbake, lcache);
1191  }
1192 
1193  /* If it is the last sample grid sample (and last bounce). */
1194  if ((lbake->bounce_curr == lbake->bounce_len - 1) && (lbake->grid_curr == lbake->grid_len - 1) &&
1195  (lbake->grid_sample == lbake->grid_sample_len - 1)) {
1196  lcache->flag &= ~LIGHTCACHE_UPDATE_GRID;
1197  }
1198 }
1199 
1200 static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
1201 {
1202  EEVEE_Data *vedata = (EEVEE_Data *)ved;
1204  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
1206  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
1207  LightCache *lcache = scene_eval->eevee.light_cache_data;
1208  EEVEE_LightProbe *eprobe = lbake->cube;
1209  LightProbe *prb = *lbake->probe;
1210  float clamp = scene_eval->eevee.gi_glossy_clamp;
1211  float filter_quality = scene_eval->eevee.gi_filter_quality;
1212 
1213  /* TODO do this once for the whole bake when we have independent DRWManagers. */
1214  eevee_lightbake_cache_create(vedata, lbake);
1215 
1216  /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
1217  common_data->spec_toggle = false;
1218  common_data->sss_toggle = false;
1219  common_data->prb_num_planar = 0;
1220  common_data->prb_num_render_cube = 0;
1221  common_data->ray_type = EEVEE_RAY_GLOSSY;
1222  common_data->ray_depth = 1;
1223  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1224 
1226  sldata, vedata, lbake->rt_fb, eprobe->position, prb->clipsta, prb->clipend);
1228  vedata,
1229  lbake->rt_color,
1230  lbake->store_fb,
1231  lbake->cube_offset,
1232  prb->intensity,
1233  lcache->mips_len,
1234  filter_quality,
1235  clamp);
1236 
1237  lcache->cube_len += 1;
1238 
1239  /* If it's the last probe. */
1240  if (lbake->cube_offset == lbake->cube_len - 1) {
1241  lcache->flag &= ~LIGHTCACHE_UPDATE_CUBE;
1242  }
1243 }
1244 
1246 {
1247  return mat4_to_scale(grid->mat);
1248 }
1249 
1251 {
1252  return mat4_to_scale(eprb->attenuationmat);
1253 }
1254 
1256 {
1257  float vol_a = eevee_lightbake_grid_influence_volume(grid_a);
1258  float vol_b = eevee_lightbake_grid_influence_volume(grid_b);
1259  return (vol_a < vol_b);
1260 }
1261 
1263 {
1264  float vol_a = eevee_lightbake_cube_influence_volume(prb_a);
1265  float vol_b = eevee_lightbake_cube_influence_volume(prb_b);
1266  return (vol_a < vol_b);
1267 }
1268 
1269 #define SORT_PROBE(elems_type, prbs, elems, elems_len, comp_fn) \
1270  { \
1271  bool sorted = false; \
1272  while (!sorted) { \
1273  sorted = true; \
1274  for (int i = 0; i < (elems_len)-1; i++) { \
1275  if ((comp_fn)((elems) + i, (elems) + i + 1)) { \
1276  SWAP(elems_type, (elems)[i], (elems)[i + 1]); \
1277  SWAP(LightProbe *, (prbs)[i], (prbs)[i + 1]); \
1278  sorted = false; \
1279  } \
1280  } \
1281  } \
1282  } \
1283  ((void)0)
1284 
1286 {
1287  Depsgraph *depsgraph = lbake->depsgraph;
1288  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
1289  LightCache *lcache = scene_eval->eevee.light_cache_data;
1290 
1291  /* At least one for the world */
1292  int grid_len = 1;
1293  int cube_len = 1;
1294  int total_irr_samples = 1;
1295 
1296  /* Convert all lightprobes to tight UBO data from all lightprobes in the scene.
1297  * This allows a large number of probe to be precomputed (even dupli ones). */
1299  const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
1300  if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
1301  continue;
1302  }
1303 
1304  if (ob->type == OB_LIGHTPROBE) {
1305  LightProbe *prb = (LightProbe *)ob->data;
1306 
1307  if (prb->type == LIGHTPROBE_TYPE_GRID) {
1308  lbake->grid_prb[grid_len] = prb;
1309  EEVEE_LightGrid *egrid = &lcache->grid_data[grid_len++];
1310  EEVEE_lightprobes_grid_data_from_object(ob, egrid, &total_irr_samples);
1311  }
1312  else if (prb->type == LIGHTPROBE_TYPE_CUBE && cube_len < EEVEE_PROBE_MAX) {
1313  lbake->cube_prb[cube_len] = prb;
1314  EEVEE_LightProbe *eprobe = &lcache->cube_data[cube_len++];
1316  }
1317  }
1318  }
1320 
1322  lbake->grid_prb + 1,
1323  lcache->grid_data + 1,
1324  lbake->grid_len - 1,
1327  lbake->cube_prb + 1,
1328  lcache->cube_data + 1,
1329  lbake->cube_len - 1,
1331 
1332  lbake->total = lbake->total_irr_samples * lbake->bounce_len + lbake->cube_len;
1333  lbake->done = 0;
1334 }
1335 
1336 void EEVEE_lightbake_update(void *custom_data)
1337 {
1338  EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
1339  Scene *scene_orig = lbake->scene;
1340 
1341  /* If a new light-cache was created, free the old one and reference the new. */
1342  if (lbake->lcache && scene_orig->eevee.light_cache_data != lbake->lcache) {
1343  if (scene_orig->eevee.light_cache_data != NULL) {
1345  }
1346  scene_orig->eevee.light_cache_data = lbake->lcache;
1347  lbake->own_light_cache = false;
1348  }
1349 
1351 
1353 }
1354 
1356  void (*render_callback)(void *ved, void *user_data))
1357 {
1358  if (G.is_break == true || *lbake->stop) {
1359  return false;
1360  }
1361 
1362  Depsgraph *depsgraph = lbake->depsgraph;
1363 
1364  /* TODO: make DRW manager instantiable (and only lock on drawing) */
1366  DRW_custom_pipeline(&draw_engine_eevee_type, depsgraph, render_callback, lbake);
1367  lbake->done += 1;
1368  *lbake->progress = lbake->done / (float)lbake->total;
1369  *lbake->do_update = 1;
1371 
1372  return true;
1373 }
1374 
1375 void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress)
1376 {
1377  EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
1378  Depsgraph *depsgraph = lbake->depsgraph;
1379 
1382 
1384  lbake->stop = stop;
1385  lbake->do_update = do_update;
1386  lbake->progress = progress;
1387 
1388  if (G.background) {
1389  /* Make sure to init GL capabilities before counting probes. */
1392  }
1393 
1394  /* Count lightprobes */
1396 
1397  /* We need to create the FBOs in the right context.
1398  * We cannot do it in the main thread. */
1401 
1402  /* Resource allocation can fail. Early exit in this case. */
1403  if (lbake->lcache->flag & LIGHTCACHE_INVALID) {
1404  *lbake->stop = 1;
1405  *lbake->do_update = 1;
1406  lbake->lcache->flag &= ~LIGHTCACHE_BAKING;
1409  return;
1410  }
1411 
1414 
1415  /* Gather all probes data */
1417 
1418  LightCache *lcache = lbake->lcache;
1419 
1420  /* HACK: Sleep to delay the first rendering operation
1421  * that causes a small freeze (caused by VBO generation)
1422  * because this step is locking at this moment. */
1423  /* TODO remove this. */
1424  if (lbake->delay) {
1425  PIL_sleep_ms(lbake->delay);
1426  }
1427 
1428  /* Render world irradiance and reflection first */
1429  if (lcache->flag & LIGHTCACHE_UPDATE_WORLD) {
1430  lbake->probe = NULL;
1432  }
1433 
1434  /* Render irradiance grids */
1435  if (lcache->flag & LIGHTCACHE_UPDATE_GRID) {
1436  for (lbake->bounce_curr = 0; lbake->bounce_curr < lbake->bounce_len; lbake->bounce_curr++) {
1437  /* Bypass world, start at 1. */
1438  lbake->probe = lbake->grid_prb + 1;
1439  lbake->grid = lcache->grid_data + 1;
1440  for (lbake->grid_curr = 1; lbake->grid_curr < lbake->grid_len;
1441  lbake->grid_curr++, lbake->probe++, lbake->grid++) {
1442  LightProbe *prb = *lbake->probe;
1443  lbake->grid_sample_len = prb->grid_resolution_x * prb->grid_resolution_y *
1444  prb->grid_resolution_z;
1445  for (lbake->grid_sample = 0; lbake->grid_sample < lbake->grid_sample_len;
1446  ++lbake->grid_sample) {
1448  }
1449  }
1450  }
1451  }
1452 
1453  /* Render reflections */
1454  if (lcache->flag & LIGHTCACHE_UPDATE_CUBE) {
1455  /* Bypass world, start at 1. */
1456  lbake->probe = lbake->cube_prb + 1;
1457  lbake->cube = lcache->cube_data + 1;
1458  for (lbake->cube_offset = 1; lbake->cube_offset < lbake->cube_len;
1459  lbake->cube_offset++, lbake->probe++, lbake->cube++) {
1461  }
1462  }
1463 
1464  /* Read the resulting lighting data to save it to file/disk. */
1469 
1470  lcache->flag |= LIGHTCACHE_BAKED;
1471  lcache->flag &= ~LIGHTCACHE_BAKING;
1472 
1473  /* Assume that if lbake->gl_context is NULL
1474  * we are not running in this in a job, so update
1475  * the scene light-cache pointer before deleting it. */
1476  if (lbake->gl_context == NULL) {
1478  EEVEE_lightbake_update(lbake);
1479  }
1480 
1482 
1483  /* Free GPU smoke textures and the smoke domain list correctly: See also T73921.*/
1485 }
1486 
1487 /* This is to update the world irradiance and reflection contribution from
1488  * within the viewport drawing (does not have the overhead of a full light cache rebuild.) */
1490  EEVEE_Data *vedata,
1491  const Scene *scene)
1492 {
1493  LightCache *lcache = vedata->stl->g_data->light_cache;
1494  float clamp = scene->eevee.gi_glossy_clamp;
1495  float filter_quality = scene->eevee.gi_filter_quality;
1496 
1497  EEVEE_LightBake lbake = {
1498  .resource_only = true,
1499  };
1500 
1501  /* Create resources. */
1503 
1504  EEVEE_lightbake_cache_init(sldata, vedata, lbake.rt_color, lbake.rt_depth);
1505 
1507  sldata->common_data.ray_depth = 1;
1508  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1509  EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
1511  vedata,
1512  lbake.rt_color,
1513  lbake.store_fb,
1514  0,
1515  1.0f,
1516  lcache->mips_len,
1517  filter_quality,
1518  clamp);
1519 
1521  sldata->common_data.ray_depth = 1;
1522  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1523  EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
1524  EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake.rt_color, lbake.store_fb, 0, 1.0f);
1525 
1526  /* Don't hide grids if they are already rendered. */
1527  lcache->grid_len = max_ii(1, lcache->grid_len);
1528  lcache->cube_len = 1;
1529 
1531  lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
1532 
1534 }
1535 
typedef float(TangentPoint)[2]
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
Definition: BKE_object.h:125
int BKE_object_visibility(const struct Object *ob, const int dag_eval_mode)
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_endian_switch_uint32_array(unsigned int *val, const int size) ATTR_NONNULL(1)
Definition: endian_switch.c:55
void BLI_endian_switch_float_array(float *val, const int size) ATTR_NONNULL(1)
Definition: endian_switch.c:65
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
MINLINE unsigned int log2_floor_u(unsigned int x)
void unit_m4(float m[4][4])
Definition: rct.c:1140
float mat4_to_scale(const float M[4][4])
Definition: math_matrix.c:2196
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3_int(int r[3])
MINLINE void negate_v3(float r[3])
void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base_10) ATTR_NONNULL()
Definition: string.c:1206
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
unsigned int uint
Definition: BLI_sys_types.h:83
void BLI_mutex_free(ThreadMutex *mutex)
Definition: threads.cc:428
ThreadMutex * BLI_mutex_alloc(void)
Definition: threads.cc:421
int BLI_thread_is_main(void)
Definition: threads.cc:234
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:401
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:406
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:83
#define MAX3(a, b, c)
#define SWAP(type, a, b)
#define UNPACK3(a)
#define MIN2(a, b)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
bool BLO_read_requires_endian_switch(BlendDataReader *reader)
Definition: readfile.c:5620
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr)
Definition: writefile.c:1286
#define TIP_(msgid)
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:281
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime)
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:314
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_graph_relations_update(struct Depsgraph *graph)
#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(graph_, instance_)
struct ViewLayer * DEG_get_evaluated_view_layer(const struct Depsgraph *graph)
#define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
Object groups, one object can be in many groups at once.
@ LIGHTCACHE_UPDATE_WORLD
@ LIGHTCACHE_BAKING
@ LIGHTCACHE_BAKED
@ LIGHTCACHE_GRID_READY
@ LIGHTCACHE_NOT_USABLE
@ LIGHTCACHE_UPDATE_GRID
@ LIGHTCACHE_CUBE_READY
@ LIGHTCACHE_INVALID
@ LIGHTCACHE_UPDATE_CUBE
@ LIGHTPROBE_FLAG_INVERT_GROUP
@ LIGHTCACHETEX_FLOAT
@ LIGHTCACHETEX_BYTE
@ LIGHTCACHETEX_UINT
#define LIGHTCACHE_STATIC_VERSION
@ LIGHTPROBE_TYPE_CUBE
@ LIGHTPROBE_TYPE_GRID
@ LIGHTCACHE_TYPE_STATIC
@ OB_LIGHTPROBE
@ SCE_EEVEE_SHADOW_HIGH_BITDEPTH
DRWTextureFlag
Definition: DRW_render.h:138
@ DRW_TEX_MIPMAP
Definition: DRW_render.h:142
@ DRW_TEX_FILTER
Definition: DRW_render.h:139
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:180
static AppView * view
int GPU_max_texture_layers(void)
bool GPU_use_main_context_workaround(void)
void GPU_context_main_lock(void)
Definition: gpu_context.cc:149
void GPU_context_discard(GPUContext *)
Definition: gpu_context.cc:113
GPUContext * GPU_context_create(void *ghost_window)
Definition: gpu_context.cc:99
void GPU_context_main_unlock(void)
Definition: gpu_context.cc:154
struct GPUFrameBuffer GPUFrameBuffer
#define GPU_FRAMEBUFFER_FREE_SAFE(fb)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei stride
GPUTexture * GPU_texture_create_2d_array(const char *name, int w, int h, int d, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:256
void GPU_texture_update_mipmap(GPUTexture *tex, int miplvl, eGPUDataFormat gpu_data_format, const void *pixels)
Definition: gpu_texture.cc:345
int GPU_texture_height(const GPUTexture *tex)
Definition: gpu_texture.cc:532
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter)
Definition: gpu_texture.cc:477
int GPU_texture_width(const GPUTexture *tex)
Definition: gpu_texture.cc:527
void * GPU_texture_read(GPUTexture *tex, eGPUDataFormat data_format, int miplvl)
Definition: gpu_texture.cc:371
@ GPU_DATA_10_11_11_REV
Definition: GPU_texture.h:177
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:175
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:172
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
Definition: gpu_texture.cc:590
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:391
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter)
Definition: gpu_texture.cc:468
@ GPU_RGBA16F
Definition: GPU_texture.h:94
@ GPU_DEPTH_COMPONENT24
Definition: GPU_texture.h:167
@ GPU_R11F_G11F_B10F
Definition: GPU_texture.h:119
GPUTexture * GPU_texture_create_cube_array(const char *name, int w, int d, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:282
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
#define MEM_SAFE_FREE(v)
Platform independent time functions.
@ WM_JOB_TYPE_LIGHT_BAKE
Definition: WM_api.h:754
@ WM_JOB_TYPE_RENDER
Definition: WM_api.h:736
@ WM_JOB_EXCL_RENDER
Definition: WM_api.h:725
@ WM_JOB_PROGRESS
Definition: WM_api.h:726
@ WM_JOB_PRIORITY
Definition: WM_api.h:724
#define NC_SCENE
Definition: WM_types.h:279
#define NA_EDITED
Definition: WM_types.h:462
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
const Depsgraph * depsgraph
void * user_data
void DRW_hair_update(void)
Definition: draw_hair.c:300
void DRW_render_viewport_size_set(const int size[2])
Definition: draw_manager.c:431
void DRW_render_instance_buffer_finish(void)
void DRW_custom_pipeline(DrawEngineType *draw_engine_type, struct Depsgraph *depsgraph, void(*callback)(void *vedata, void *user_data), void *user_data)
void DRW_render_object_iter(void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph, void(*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
const DRWView * DRW_view_default_get(void)
DRWView * DRW_view_create(const float viewmat[4][4], const float winmat[4][4], const float(*culling_viewmat)[4], const float(*culling_winmat)[4], DRWCallVisibilityFn *visibility_fn)
void DRW_view_default_set(DRWView *view)
void DRW_view_set_active(DRWView *view)
void DRW_draw_pass(DRWPass *pass)
GPUTexture * DRW_texture_create_cube_array(int w, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
GPUTexture * DRW_texture_create_cube(int w, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
GPUTexture * DRW_texture_create_2d_array(int w, int h, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
EEVEE_ViewLayerData * EEVEE_view_layer_data_ensure(void)
Definition: eevee_data.c:276
void EEVEE_view_layer_data_free(void *storage)
Definition: eevee_data.c:208
void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera, const bool minimal)
Definition: eevee_effects.c:71
void EEVEE_effects_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
DrawEngineType draw_engine_eevee_type
Definition: eevee_engine.c:622
void * EEVEE_lightbake_job_data_alloc(struct Main *bmain, struct ViewLayer *view_layer, struct Scene *scene, bool run_as_job, int frame)
static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
#define IRRADIANCE_MAX_POOL_LAYER
static void eevee_lightbake_create_render_target(EEVEE_LightBake *lbake, int rt_res)
#define IRRADIANCE_SAMPLE_SIZE_X
void DRW_gpu_render_context_enable(void *re_gpu_context)
static float eevee_lightbake_grid_influence_volume(EEVEE_LightGrid *grid)
static void eevee_lightbake_readback_reflections(LightCache *lcache)
static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
void DRW_opengl_context_enable(void)
static bool eevee_lightbake_cube_comp(EEVEE_LightProbe *prb_a, EEVEE_LightProbe *prb_b)
LightCache * EEVEE_lightcache_create(const int grid_len, const int cube_len, const int cube_size, const int vis_size, const int irr_size[3])
bool EEVEE_lightcache_load(LightCache *lcache)
static void eevee_lightbake_readback_irradiance(LightCache *lcache)
static bool lightbake_do_sample(EEVEE_LightBake *lbake, void(*render_callback)(void *ved, void *user_data))
static bool eevee_lightcache_static_load(LightCache *lcache)
static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
static void compute_cell_id(EEVEE_LightGrid *egrid, LightProbe *probe, int cell_idx, int *r_final_idx, int r_local_cell[3], int *r_stride)
static void eevee_lightbake_copy_irradiance(EEVEE_LightBake *lbake, LightCache *lcache)
void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress)
void DRW_opengl_render_context_disable(void *re_gl_context)
void EEVEE_lightcache_blend_read_data(BlendDataReader *reader, LightCache *cache)
#define IRRADIANCE_SAMPLE_SIZE_Y
void DRW_gpu_render_context_disable(void *re_gpu_context)
static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lbake)
void EEVEE_lightcache_blend_write(BlendWriter *writer, LightCache *cache)
static bool eevee_lightcache_can_be_saved(LightCache *lcache)
static uint eevee_lightcache_memsize_get(LightCache *lcache)
static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
wmJob * EEVEE_lightbake_job_create(struct wmWindowManager *wm, struct wmWindow *win, struct Main *bmain, struct ViewLayer *view_layer, struct Scene *scene, int delay, int frame)
#define IRRADIANCE_MAX_POOL_SIZE
static bool EEVEE_lightcache_validate(const LightCache *light_cache, const int cube_len, const int cube_res, const int grid_len, const int irr_size[3])
#define IRRADIANCE_FORMAT
static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
static bool eevee_lightbake_grid_comp(EEVEE_LightGrid *grid_a, EEVEE_LightGrid *grid_b)
static void direct_link_lightcache_texture(BlendDataReader *reader, LightCacheTexture *lctex)
void DRW_opengl_render_context_enable(void *re_gl_context)
static void cell_id_to_grid_loc(EEVEE_LightGrid *egrid, int cell_idx, int r_local_cell[3])
void EEVEE_lightbake_job_data_free(void *custom_data)
static bool eevee_lightcache_version_check(const LightCache *lcache)
struct EEVEE_LightBake EEVEE_LightBake
static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, const int local_cell[3], float r_pos[3])
static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
void DRW_opengl_context_disable(void)
static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
void EEVEE_lightcache_free(LightCache *lcache)
void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
static float eevee_lightbake_cube_influence_volume(EEVEE_LightProbe *eprb)
static void irradiance_pool_size_get(int visibility_size, int total_samples, int r_size[3])
void EEVEE_lightbake_update(void *custom_data)
static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
void EEVEE_lightbake_update_world_quick(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, const Scene *scene)
#define SORT_PROBE(elems_type, prbs, elems, elems_len, comp_fn)
static void write_lightcache_texture(BlendWriter *writer, LightCacheTexture *tex)
void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, GPUTexture *rt_color, GPUTexture *rt_depth)
void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *eprobe)
void EEVEE_lightbake_render_world(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, struct GPUFrameBuffer *face_fb[6])
void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_lightprobes_grid_data_from_object(Object *ob, EEVEE_LightGrid *egrid, int *offset)
void EEVEE_lightbake_render_scene(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUFrameBuffer *face_fb[6], const float pos[3], float near_clip, float far_clip)
void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *rt_color, struct GPUFrameBuffer *fb, int grid_offset, float intensity)
void EEVEE_lightbake_filter_visibility(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *UNUSED(rt_depth), struct GPUFrameBuffer *fb, int grid_offset, float clipsta, float clipend, float vis_range, float vis_blur, int vis_size)
void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUTexture *rt_color, struct GPUFrameBuffer *fb, int probe_idx, float intensity, int maxlevel, float filter_quality, float firefly_fac)
void EEVEE_lights_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
Definition: eevee_lights.c:246
void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
Definition: eevee_lights.c:208
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, EEVEE_StorageList *stl, EEVEE_FramebufferList *fbl)
void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_shadows_update(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
#define MIN_CUBE_LOD_LEVEL
void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_render_cache(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph)
Definition: eevee_render.c:198
void EEVEE_volumes_free_smoke_textures(void)
void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
#define EEVEE_PROBE_MAX
Definition: eevee_private.h:88
#define EEVEE_RAY_DIFFUSE
#define EEVEE_RAY_GLOSSY
void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata)
Definition: eevee_shadows.c:41
@ EFFECT_VOLUMETRIC
void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_volumes_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
uint pos
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
#define ceilf(x)
#define floorf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:40
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
EEVEE_EffectsFlag enabled_effects
EEVEE_LightGrid * grid
Depsgraph * depsgraph
LightProbe ** cube_prb
ViewLayer * view_layer_input
struct GPUTexture * dummy_color
GPUFrameBuffer * rt_fb[6]
struct GPUTexture * dummy_depth
LightProbe ** probe
LightProbe ** grid_prb
GPUFrameBuffer * store_fb
EEVEE_ViewLayerData * sldata
LightCache * lcache
ThreadMutex * mutex
ViewLayer * view_layer
GPUTexture * rt_depth
GPUTexture * rt_color
EEVEE_LightProbe * cube
GPUTexture * grid_prev
struct Main * bmain
struct GPUTexture * dummy_layer_color
struct Collection * collection
EEVEE_LightProbeVisTest vis_data
struct DRWPass * probe_grid_fill
struct LightCache * light_cache
struct EEVEE_PrivateData * g_data
struct EEVEE_EffectsInfo * effects
struct GPUTexture * color
struct EEVEE_CommonUniformBuffer common_data
struct GPUUniformBuf * common_ubo
struct EEVEE_LightProbesInfo * probes
struct GPUTexture * tex
LightGridCache * grid_data
LightProbeCache * cube_data
LightCacheTexture grid_tx
LightCacheTexture * cube_mips
LightCacheTexture cube_tx
float attenuationmat[4][4]
struct Collection * visibility_grp
Definition: BKE_main.h:116
float gi_glossy_clamp
float gi_irradiance_smoothing
struct LightCache * light_cache_data
int gi_visibility_resolution
float gi_filter_quality
char light_cache_info[64]
int gi_cubemap_resolution
struct SceneEEVEE eevee
Definition: wm_jobs.c:73
void PIL_sleep_ms(int ms)
Definition: time.c:100
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
#define G(x, y, z)
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:196
bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
Definition: wm_jobs.c:223
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition: wm_jobs.c:372
void * WM_jobs_customdata_get(wmJob *wm_job)
Definition: wm_jobs.c:336
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:344
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:360
void * WM_opengl_context_create(void)
Definition: wm_window.c:2421
void wm_window_reset_drawable(void)
Definition: wm_window.c:1074
void WM_opengl_context_dispose(void *context)
Definition: wm_window.c:2437