Blender  V3.3
eevee_lightcache.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. */
3 
10 #include "DRW_render.h"
11 
12 #include "BKE_global.h"
13 
14 #include "BLI_endian_switch.h"
15 #include "BLI_threads.h"
16 
17 #include "DEG_depsgraph_build.h"
18 #include "DEG_depsgraph_query.h"
19 
20 #include "BKE_object.h"
21 
22 #include "DNA_collection_types.h"
23 #include "DNA_lightprobe_types.h"
24 
25 #include "PIL_time.h"
26 
27 #include "eevee_lightcache.h"
28 #include "eevee_private.h"
29 
30 #include "GPU_capabilities.h"
31 #include "GPU_context.h"
32 
33 #include "WM_api.h"
34 #include "WM_types.h"
35 
36 #include "BLO_read_write.h"
37 
38 #include "wm_window.h"
39 
40 /* Rounded to nearest PowerOfTwo */
41 #if defined(IRRADIANCE_SH_L2)
42 # define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
43 # define IRRADIANCE_SAMPLE_SIZE_Y 4 /* 3 in reality */
44 #elif defined(IRRADIANCE_HL2)
45 # define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
46 # define IRRADIANCE_SAMPLE_SIZE_Y 2
47 #endif
48 
49 #ifdef IRRADIANCE_SH_L2
50 /* we need a signed format for Spherical Harmonics */
51 # define IRRADIANCE_FORMAT GPU_RGBA16F
52 #else
53 # define IRRADIANCE_FORMAT GPU_RGBA8
54 #endif
55 
56 /* OpenGL 3.3 core requirement, can be extended but it's already very big */
57 #define IRRADIANCE_MAX_POOL_LAYER 256
58 #define IRRADIANCE_MAX_POOL_SIZE 1024
59 #define MAX_IRRADIANCE_SAMPLES \
60  (IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_X) * \
61  (IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_Y)
62 
63 /* TODO: should be replace by a more elegant alternative. */
64 extern void DRW_opengl_context_enable(void);
65 extern void DRW_opengl_context_disable(void);
66 
67 extern void DRW_opengl_render_context_enable(void *re_gl_context);
68 extern void DRW_opengl_render_context_disable(void *re_gl_context);
69 extern void DRW_gpu_render_context_enable(void *re_gpu_context);
70 extern void DRW_gpu_render_context_disable(void *re_gpu_context);
71 
72 typedef struct EEVEE_LightBake {
78  struct Main *bmain;
80 
92  int rt_res;
93 
94  /* Shared */
96  int layer;
100  float lod_factor;
102  float lod_max;
105 
106  /* Irradiance grid */
112  int irr_size[3];
124  float vis_res;
129 
130  /* Reflection probe */
139 
140  /* Dummy Textures */
143 
144  int total, done; /* to compute progress */
145  short *stop, *do_update;
146  float *progress;
147 
154  int delay;
156  int frame;
157 
160 
163 
164 /* -------------------------------------------------------------------- */
168 /* Return memory footprint in bytes. */
170 {
171  uint size = 0;
172  if (lcache->grid_tx.data) {
173  size += MEM_allocN_len(lcache->grid_tx.data);
174  }
175  if (lcache->cube_tx.data) {
176  size += MEM_allocN_len(lcache->cube_tx.data);
177  for (int mip = 0; mip < lcache->mips_len; mip++) {
178  size += MEM_allocN_len(lcache->cube_mips[mip].data);
179  }
180  }
181  return size;
182 }
183 
184 static bool eevee_lightcache_version_check(const LightCache *lcache)
185 {
186  switch (lcache->type) {
188  return lcache->version == LIGHTCACHE_STATIC_VERSION;
189  default:
190  return false;
191  }
192 }
193 
195 {
196  if (lcache->grid_tx.data) {
197  if (MEM_allocN_len(lcache->grid_tx.data) >= INT_MAX) {
198  return false;
199  }
200  }
201  if (lcache->cube_tx.data) {
202  if (MEM_allocN_len(lcache->cube_tx.data) >= INT_MAX) {
203  return false;
204  }
205  }
206  return true;
207 }
208 
210 {
211  int total_irr_samples = 0;
212 
213  for (int i = 1; i < lcache->grid_len; i++) {
214  EEVEE_LightGrid *egrid = lcache->grid_data + i;
215  total_irr_samples += egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2];
216  }
217  return total_irr_samples;
218 }
219 
221 {
222  LightCache *lcache = eevee->light_cache_data;
223 
224  if (lcache != NULL) {
225  if (!eevee_lightcache_version_check(lcache)) {
227  TIP_("Incompatible Light cache version, please bake again"),
228  sizeof(eevee->light_cache_info));
229  return;
230  }
231 
232  if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
234  TIP_("Error: Light cache is too big for the GPU to be loaded"),
235  sizeof(eevee->light_cache_info));
236  return;
237  }
238 
239  if (lcache->flag & LIGHTCACHE_INVALID) {
241  TIP_("Error: Light cache dimensions not supported by the GPU"),
242  sizeof(eevee->light_cache_info));
243  return;
244  }
245 
246  if (lcache->flag & LIGHTCACHE_BAKING) {
247  BLI_strncpy(
248  eevee->light_cache_info, TIP_("Baking light cache"), sizeof(eevee->light_cache_info));
249  return;
250  }
251 
252  if (!eevee_lightcache_can_be_saved(lcache)) {
254  TIP_("Error: LightCache is too large and will not be saved to disk"),
255  sizeof(eevee->light_cache_info));
256  return;
257  }
258 
259  char formatted_mem[15];
260  BLI_str_format_byte_unit(formatted_mem, eevee_lightcache_memsize_get(lcache), false);
261 
262  int irr_samples = eevee_lightcache_irradiance_sample_count(lcache);
263 
265  sizeof(eevee->light_cache_info),
266  TIP_("%d Ref. Cubemaps, %d Irr. Samples (%s in memory)"),
267  lcache->cube_len - 1,
268  irr_samples,
269  formatted_mem);
270  }
271  else {
273  TIP_("No light cache in this scene"),
274  sizeof(eevee->light_cache_info));
275  }
276 }
277 
278 static void irradiance_pool_size_get(int visibility_size, int total_samples, int r_size[3])
279 {
280  /* Compute how many irradiance samples we can store per visibility sample. */
281  int irr_per_vis = (visibility_size / IRRADIANCE_SAMPLE_SIZE_X) *
282  (visibility_size / IRRADIANCE_SAMPLE_SIZE_Y);
283 
284  /* The irradiance itself take one layer, hence the +1 */
285  int layer_count = MIN2(irr_per_vis + 1, IRRADIANCE_MAX_POOL_LAYER);
286 
287  int texel_count = (int)ceilf((float)total_samples / (float)(layer_count - 1));
288  r_size[0] = visibility_size *
289  max_ii(1, min_ii(texel_count, (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
290  r_size[1] = visibility_size *
291  max_ii(1, (texel_count / (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
292  r_size[2] = layer_count;
293 }
294 
295 static bool EEVEE_lightcache_validate(const LightCache *light_cache,
296  const int cube_len,
297  const int cube_res,
298  const int grid_len,
299  const int irr_size[3])
300 {
301  if (light_cache == NULL) {
302  return false;
303  }
304  if (!eevee_lightcache_version_check(light_cache)) {
305  return false;
306  }
307 
308  if (!(light_cache->flag & LIGHTCACHE_INVALID)) {
309  /* See if we need the same amount of texture space. */
310  if ((irr_size[0] == light_cache->grid_tx.tex_size[0]) &&
311  (irr_size[1] == light_cache->grid_tx.tex_size[1]) &&
312  (irr_size[2] == light_cache->grid_tx.tex_size[2]) && (grid_len == light_cache->grid_len)) {
313  int mip_len = log2_floor_u(cube_res) - MIN_CUBE_LOD_LEVEL;
314  if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
315  (cube_len == light_cache->cube_tx.tex_size[2] / 6) &&
316  (cube_len == light_cache->cube_len) && (mip_len == light_cache->mips_len)) {
317  return true;
318  }
319  }
320  }
321  return false;
322 }
323 
325  const int cube_len,
326  const int cube_size,
327  const int vis_size,
328  const int irr_size[3])
329 {
330  LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
331 
332  light_cache->version = LIGHTCACHE_STATIC_VERSION;
333  light_cache->type = LIGHTCACHE_TYPE_STATIC;
334 
335  light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
336  light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
337 
338  light_cache->grid_tx.tex = DRW_texture_create_2d_array(
339  irr_size[0], irr_size[1], irr_size[2], IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
340  light_cache->grid_tx.tex_size[0] = irr_size[0];
341  light_cache->grid_tx.tex_size[1] = irr_size[1];
342  light_cache->grid_tx.tex_size[2] = irr_size[2];
343 
344  int mips_len = log2_floor_u(cube_size) - MIN_CUBE_LOD_LEVEL;
345 
346  /* Try to create a cubemap array. */
349  cube_size, cube_len, GPU_R11F_G11F_B10F, cube_texflag, NULL);
350  if (light_cache->cube_tx.tex == NULL) {
351  /* Try fallback to 2D array. */
352  light_cache->cube_tx.tex = DRW_texture_create_2d_array(
353  cube_size, cube_size, cube_len * 6, GPU_R11F_G11F_B10F, cube_texflag, NULL);
354  }
355 
356  light_cache->cube_tx.tex_size[0] = cube_size;
357  light_cache->cube_tx.tex_size[1] = cube_size;
358  light_cache->cube_tx.tex_size[2] = cube_len * 6;
359 
360  light_cache->mips_len = mips_len;
361  light_cache->vis_res = vis_size;
362  light_cache->ref_res = cube_size;
363 
364  light_cache->cube_mips = MEM_callocN(sizeof(LightCacheTexture) * light_cache->mips_len,
365  "LightCacheTexture");
366 
367  if (light_cache->grid_tx.tex == NULL || light_cache->cube_tx.tex == NULL) {
368  /* We could not create the requested textures size. Stop baking and do not use the cache. */
369  light_cache->flag = LIGHTCACHE_INVALID;
370  }
371  else {
373 
374  for (int mip = 0; mip < light_cache->mips_len; mip++) {
376  light_cache->cube_tx.tex, mip + 1, light_cache->cube_mips[mip].tex_size);
377  }
378  }
379 
380  return light_cache;
381 }
382 
384 {
385  /* We use fallback if a texture is not setup and there is no data to restore it. */
386  if ((!lcache->grid_tx.tex && !lcache->grid_tx.data) || !lcache->grid_data ||
387  (!lcache->cube_tx.tex && !lcache->cube_tx.data) || !lcache->cube_data) {
388  return false;
389  }
390  /* If cache is too big for this GPU. */
391  if (lcache->cube_tx.tex_size[2] > GPU_max_texture_layers()) {
392  return false;
393  }
394 
395  if (lcache->grid_tx.tex == NULL) {
397  "lightcache_irradiance", UNPACK3(lcache->grid_tx.tex_size), 1, IRRADIANCE_FORMAT, NULL);
399 
400  if (lcache->grid_tx.tex == NULL) {
401  lcache->flag |= LIGHTCACHE_NOT_USABLE;
402  return false;
403  }
404 
405  GPU_texture_filter_mode(lcache->grid_tx.tex, true);
406  }
407 
408  if (lcache->cube_tx.tex == NULL) {
409  /* Try to create a cubemap array. */
410  lcache->cube_tx.tex = GPU_texture_create_cube_array("lightcache_cubemaps",
411  lcache->cube_tx.tex_size[0],
412  lcache->cube_tx.tex_size[2] / 6,
413  lcache->mips_len + 1,
415  NULL);
416 
417  if (lcache->cube_tx.tex == NULL) {
418  /* Try fallback to 2D array. */
419  lcache->cube_tx.tex = GPU_texture_create_2d_array("lightcache_cubemaps_fallback",
420  UNPACK3(lcache->cube_tx.tex_size),
421  lcache->mips_len + 1,
423  NULL);
424  }
425 
426  if (lcache->cube_tx.tex == NULL) {
427  lcache->flag |= LIGHTCACHE_NOT_USABLE;
428  return false;
429  }
430 
431  for (int mip = 0; mip <= lcache->mips_len; mip++) {
432  const void *data = (mip == 0) ? lcache->cube_tx.data : lcache->cube_mips[mip - 1].data;
434  }
435  GPU_texture_mipmap_mode(lcache->cube_tx.tex, true, true);
436  }
437  return true;
438 }
439 
441 {
442  if (lcache == NULL) {
443  return false;
444  }
445 
446  if (!eevee_lightcache_version_check(lcache)) {
447  return false;
448  }
449 
450  if (lcache->flag & (LIGHTCACHE_INVALID | LIGHTCACHE_NOT_USABLE)) {
451  return false;
452  }
453 
454  switch (lcache->type) {
456  return eevee_lightcache_static_load(lcache);
457  default:
458  return false;
459  }
460 }
461 
463 {
464  MEM_SAFE_FREE(lcache->grid_tx.data);
465  lcache->grid_tx.data = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_UBYTE, 0);
467  lcache->grid_tx.components = 4;
468 }
469 
471 {
472  MEM_SAFE_FREE(lcache->cube_tx.data);
475  lcache->cube_tx.components = 1;
476 
477  for (int mip = 0; mip < lcache->mips_len; mip++) {
478  LightCacheTexture *cube_mip = lcache->cube_mips + mip;
479  MEM_SAFE_FREE(cube_mip->data);
480  GPU_texture_get_mipmap_size(lcache->cube_tx.tex, mip + 1, cube_mip->tex_size);
481 
482  cube_mip->data = GPU_texture_read(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1);
483  cube_mip->data_type = LIGHTCACHETEX_UINT;
484  cube_mip->components = 1;
485  }
486 }
487 
489 {
491  MEM_SAFE_FREE(lcache->cube_tx.data);
493  MEM_SAFE_FREE(lcache->grid_tx.data);
494 
495  if (lcache->cube_mips) {
496  for (int i = 0; i < lcache->mips_len; i++) {
497  MEM_SAFE_FREE(lcache->cube_mips[i].data);
498  }
499  MEM_SAFE_FREE(lcache->cube_mips);
500  }
501 
502  MEM_SAFE_FREE(lcache->cube_data);
503  MEM_SAFE_FREE(lcache->grid_data);
504  MEM_freeN(lcache);
505 }
506 
508 {
509  if (tex->data) {
510  size_t data_size = tex->components * tex->tex_size[0] * tex->tex_size[1] * tex->tex_size[2];
511  if (tex->data_type == LIGHTCACHETEX_FLOAT) {
512  data_size *= sizeof(float);
513  }
514  else if (tex->data_type == LIGHTCACHETEX_UINT) {
515  data_size *= sizeof(uint);
516  }
517 
518  /* FIXME: We can't save more than what 32bit systems can handle.
519  * The solution would be to split the texture but it is too late for 2.90. (see T78529) */
520  if (data_size < INT_MAX) {
521  BLO_write_raw(writer, data_size, tex->data);
522  }
523  }
524 }
525 
527 {
528  write_lightcache_texture(writer, &cache->grid_tx);
529  write_lightcache_texture(writer, &cache->cube_tx);
530 
531  if (cache->cube_mips) {
533  for (int i = 0; i < cache->mips_len; i++) {
534  write_lightcache_texture(writer, &cache->cube_mips[i]);
535  }
536  }
537 
538  BLO_write_struct_array(writer, LightGridCache, cache->grid_len, cache->grid_data);
539  BLO_write_struct_array(writer, LightProbeCache, cache->cube_len, cache->cube_data);
540 }
541 
543 {
544  lctex->tex = NULL;
545 
546  if (lctex->data) {
547  BLO_read_data_address(reader, &lctex->data);
548  if (lctex->data && BLO_read_requires_endian_switch(reader)) {
549  int data_size = lctex->components * lctex->tex_size[0] * lctex->tex_size[1] *
550  lctex->tex_size[2];
551 
552  if (lctex->data_type == LIGHTCACHETEX_FLOAT) {
553  BLI_endian_switch_float_array((float *)lctex->data, data_size * sizeof(float));
554  }
555  else if (lctex->data_type == LIGHTCACHETEX_UINT) {
556  BLI_endian_switch_uint32_array((uint *)lctex->data, data_size * sizeof(uint));
557  }
558  }
559  }
560 
561  if (lctex->data == NULL) {
562  zero_v3_int(lctex->tex_size);
563  }
564 }
565 
567 {
568  cache->flag &= ~LIGHTCACHE_NOT_USABLE;
569  direct_link_lightcache_texture(reader, &cache->cube_tx);
570  direct_link_lightcache_texture(reader, &cache->grid_tx);
571 
572  if (cache->cube_mips) {
573  BLO_read_data_address(reader, &cache->cube_mips);
574  for (int i = 0; i < cache->mips_len; i++) {
575  direct_link_lightcache_texture(reader, &cache->cube_mips[i]);
576  }
577  }
578 
579  BLO_read_data_address(reader, &cache->cube_data);
580  BLO_read_data_address(reader, &cache->grid_data);
581 }
582 
585 /* -------------------------------------------------------------------- */
590 {
594  return;
595  }
596 
597  if (lbake->gl_context) {
599  if (lbake->gpu_context == NULL) {
601  }
603  }
604  else {
606  }
607 }
608 
610 {
614  return;
615  }
616 
617  if (lbake->gl_context) {
620  }
621  else {
623  }
624 }
625 
628 /* -------------------------------------------------------------------- */
633 {
634  Depsgraph *depsgraph = lbake->depsgraph;
635 
636  /* At least one of each for the world */
637  lbake->grid_len = lbake->cube_len = lbake->total_irr_samples = 1;
638 
640  const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
641  if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
642  continue;
643  }
644 
645  if (ob->type == OB_LIGHTPROBE) {
646  LightProbe *prb = (LightProbe *)ob->data;
647 
648  if (prb->type == LIGHTPROBE_TYPE_GRID) {
650  prb->grid_resolution_z;
651  lbake->grid_len++;
652  }
653  else if (prb->type == LIGHTPROBE_TYPE_CUBE && lbake->cube_len < EEVEE_PROBE_MAX) {
654  lbake->cube_len++;
655  }
656  }
657  }
659 }
660 
662 {
666 
667  for (int i = 0; i < 6; i++) {
668  GPU_framebuffer_ensure_config(&lbake->rt_fb[i],
669  {GPU_ATTACHMENT_TEXTURE_CUBEFACE(lbake->rt_depth, i),
670  GPU_ATTACHMENT_TEXTURE_CUBEFACE(lbake->rt_color, i)});
671  }
672 
673  GPU_framebuffer_ensure_config(&lbake->store_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_NONE});
674 }
675 
677 {
678  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
679  SceneEEVEE *eevee = &scene_eval->eevee;
680 
681  lbake->bounce_len = eevee->gi_diffuse_bounces;
682  lbake->vis_res = eevee->gi_visibility_resolution;
683  lbake->rt_res = eevee->gi_cubemap_resolution;
684 
686 
687  lbake->ref_cube_res = lbake->rt_res;
688  lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
689  lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
690 
692  lbake->irr_size[1],
693  lbake->irr_size[2],
696  NULL);
697 
698  /* Ensure Light Cache is ready to accept new data. If not recreate one.
699  * WARNING: All the following must be threadsafe. It's currently protected
700  * by the DRW mutex. */
701  lbake->lcache = eevee->light_cache_data;
702 
703  /* TODO: validate irradiance and reflection cache independently... */
705  lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->grid_len, lbake->irr_size)) {
706  eevee->light_cache_data = lbake->lcache = NULL;
707  }
708 
709  if (lbake->lcache == NULL) {
711  lbake->grid_len, lbake->cube_len, lbake->ref_cube_res, lbake->vis_res, lbake->irr_size);
712 
713  lbake->own_light_cache = true;
714 
715  eevee->light_cache_data = lbake->lcache;
716  }
717 
719 
720  lbake->lcache->flag |= LIGHTCACHE_BAKING;
721  lbake->lcache->cube_len = 1;
722 }
723 
725  struct wmWindow *win,
726  struct Main *bmain,
727  struct ViewLayer *view_layer,
728  struct Scene *scene,
729  int delay,
730  int frame)
731 {
732  EEVEE_LightBake *lbake = NULL;
733 
734  /* only one render job at a time */
736  return NULL;
737  }
738 
739  wmJob *wm_job = WM_jobs_get(wm,
740  win,
741  scene,
742  "Bake Lighting",
745 
746  /* If job exists do not recreate context and depsgraph. */
748 
749  if (old_lbake && (old_lbake->view_layer_input == view_layer) && (old_lbake->bmain == bmain)) {
750  lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
751  /* Cannot reuse depsgraph for now because we cannot get the update from the
752  * main database directly. TODO: reuse depsgraph and only update positions. */
753  /* lbake->depsgraph = old_lbake->depsgraph; */
754  lbake->depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
755 
756  lbake->mutex = BLI_mutex_alloc();
757 
758  BLI_mutex_lock(old_lbake->mutex);
759  old_lbake->own_resources = false;
760 
761  lbake->scene = scene;
762  lbake->bmain = bmain;
763  lbake->view_layer_input = view_layer;
764  lbake->gl_context = old_lbake->gl_context;
765  lbake->own_resources = true;
766  lbake->delay = delay;
767  lbake->frame = frame;
768 
769  if (lbake->gl_context == NULL && !GPU_use_main_context_workaround()) {
772  }
773 
774  if (old_lbake->stop != NULL) {
775  *old_lbake->stop = 1;
776  }
777  BLI_mutex_unlock(old_lbake->mutex);
778  }
779  else {
780  lbake = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, true, frame);
781  lbake->delay = delay;
782  }
783 
785  WM_jobs_timer(wm_job, 0.4, NC_SCENE | NA_EDITED, 0);
788 
789  G.is_break = false;
790 
791  return wm_job;
792 }
793 
795  struct ViewLayer *view_layer,
796  struct Scene *scene,
797  bool run_as_job,
798  int frame)
799 {
801 
802  EEVEE_LightBake *lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
803 
804  lbake->depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
805  lbake->scene = scene;
806  lbake->bmain = bmain;
807  lbake->view_layer_input = view_layer;
808  lbake->own_resources = true;
809  lbake->own_light_cache = false;
810  lbake->mutex = BLI_mutex_alloc();
811  lbake->frame = frame;
812 
813  if (run_as_job && !GPU_use_main_context_workaround()) {
816  }
817 
818  return lbake;
819 }
820 
821 void EEVEE_lightbake_job_data_free(void *custom_data)
822 {
823  EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
824 
825  /* TODO: reuse depsgraph. */
826  /* if (lbake->own_resources) { */
827  DEG_graph_free(lbake->depsgraph);
828  /* } */
829 
830  MEM_SAFE_FREE(lbake->cube_prb);
831  MEM_SAFE_FREE(lbake->grid_prb);
832 
833  BLI_mutex_free(lbake->mutex);
834 
835  MEM_freeN(lbake);
836 }
837 
839 {
840  if (!lbake->resource_only) {
841  BLI_mutex_lock(lbake->mutex);
842  }
843 
844  if (lbake->gl_context) {
847  }
848  else if (!lbake->resource_only) {
850  }
851 
852  /* XXX Free the resources contained in the viewlayer data
853  * to be able to free the context before deleting the depsgraph. */
854  if (lbake->sldata) {
856  }
857 
861  GPU_FRAMEBUFFER_FREE_SAFE(lbake->store_fb);
862  for (int i = 0; i < 6; i++) {
863  GPU_FRAMEBUFFER_FREE_SAFE(lbake->rt_fb[i]);
864  }
865 
866  if (lbake->gpu_context) {
870  }
871 
872  if (lbake->gl_context && lbake->own_resources) {
873  /* Delete the baking context. */
876  lbake->gpu_context = NULL;
877  lbake->gl_context = NULL;
878  }
879  else if (lbake->gl_context) {
881  }
882  else if (!lbake->resource_only) {
884  }
885 
886  if (!lbake->resource_only) {
887  BLI_mutex_unlock(lbake->mutex);
888  }
889 }
890 
891 /* Cache as in draw cache not light cache. */
893 {
894  EEVEE_TextureList *txl = vedata->txl;
895  EEVEE_StorageList *stl = vedata->stl;
896  EEVEE_FramebufferList *fbl = vedata->fbl;
898  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
899  lbake->sldata = sldata;
900 
901  /* Disable all effects BUT high bit-depth shadows. */
903  scene_eval->eevee.taa_samples = 1;
904  scene_eval->eevee.gi_irradiance_smoothing = 0.0f;
905 
906  stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
907  stl->g_data->background_alpha = 1.0f;
908  stl->g_data->render_timesteps = 1;
909 
910  /* XXX TODO: remove this. This is in order to make the init functions work. */
911  if (DRW_view_default_get() == NULL) {
912  float winmat[4][4], viewmat[4][4];
913  unit_m4(viewmat);
914  unit_m4(winmat);
915  negate_v3(winmat[2]);
916  DRWView *view = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
919  }
920 
921  /* HACK: set txl->color but unset it before Draw Manager frees it. */
922  txl->color = lbake->rt_color;
923  const int viewport_size[2] = {
924  GPU_texture_width(txl->color),
926  };
927  DRW_render_viewport_size_set(viewport_size);
928 
929  EEVEE_effects_init(sldata, vedata, NULL, true);
930  EEVEE_materials_init(sldata, vedata, stl, fbl);
931  EEVEE_shadows_init(sldata);
932  EEVEE_lightprobes_init(sldata, vedata);
933 
934  EEVEE_effects_cache_init(sldata, vedata);
935  EEVEE_materials_cache_init(sldata, vedata);
936  EEVEE_subsurface_cache_init(sldata, vedata);
937  EEVEE_volumes_cache_init(sldata, vedata);
938  EEVEE_lights_cache_init(sldata, vedata);
939  EEVEE_lightprobes_cache_init(sldata, vedata);
940 
941  EEVEE_lightbake_cache_init(sldata, vedata, lbake->rt_color, lbake->rt_depth);
942 
943  if (lbake->probe) {
944  EEVEE_LightProbesInfo *pinfo = sldata->probes;
945  LightProbe *prb = *lbake->probe;
946  pinfo->vis_data.collection = prb->visibility_grp;
948  pinfo->vis_data.cached = false;
949  }
951 
952  EEVEE_volumes_cache_finish(sldata, vedata);
953  EEVEE_materials_cache_finish(sldata, vedata);
954  EEVEE_lights_cache_finish(sldata, vedata);
955  EEVEE_lightprobes_cache_finish(sldata, vedata);
956  EEVEE_shadows_update(sldata, vedata);
957 
958  /* Disable volumetrics when baking. */
960 
961  EEVEE_subsurface_draw_init(sldata, vedata);
962  EEVEE_effects_draw_init(sldata, vedata);
963  EEVEE_volumes_draw_init(sldata, vedata);
964 
965  txl->color = NULL;
966 
969 }
970 
972 {
974 
975  /* Copy texture by reading back and re-uploading it. */
976  float *tex = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_FLOAT, 0);
978  lbake->irr_size[1],
979  lbake->irr_size[2],
982  tex);
983 
984  MEM_freeN(tex);
985 }
986 
987 static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
988 {
989  EEVEE_Data *vedata = (EEVEE_Data *)ved;
992  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
993  LightCache *lcache = scene_eval->eevee.light_cache_data;
994  float clamp = scene_eval->eevee.gi_glossy_clamp;
995  float filter_quality = scene_eval->eevee.gi_filter_quality;
996 
997  /* TODO: do this once for the whole bake when we have independent DRWManagers. */
998  eevee_lightbake_cache_create(vedata, lbake);
999 
1001  sldata->common_data.ray_depth = 1;
1002  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1003  EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
1005  vedata,
1006  lbake->rt_color,
1007  lbake->store_fb,
1008  0,
1009  1.0f,
1010  lcache->mips_len,
1011  filter_quality,
1012  clamp);
1013 
1015  sldata->common_data.ray_depth = 1;
1016  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1017  EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
1018  EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f);
1019 
1020  if (lcache->flag & LIGHTCACHE_UPDATE_GRID) {
1021  /* Clear the cache to avoid white values in the grid. */
1022  GPU_framebuffer_texture_attach(lbake->store_fb, lbake->grid_prev, 0, 0);
1024  /* Clear to 1.0f for visibility. */
1025  GPU_framebuffer_clear_color(lbake->store_fb, ((float[4]){1.0f, 1.0f, 1.0f, 1.0f}));
1026  DRW_draw_pass(vedata->psl->probe_grid_fill);
1027 
1028  SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
1029 
1030  /* Make a copy for later. */
1031  eevee_lightbake_copy_irradiance(lbake, lcache);
1032  }
1033 
1034  lcache->cube_len = 1;
1035  lcache->grid_len = lbake->grid_len;
1036 
1038  lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
1039 }
1040 
1041 static void cell_id_to_grid_loc(EEVEE_LightGrid *egrid, int cell_idx, int r_local_cell[3])
1042 {
1043  /* Keep in sync with lightprobe_grid_display_vert */
1044  r_local_cell[2] = cell_idx % egrid->resolution[2];
1045  r_local_cell[1] = (cell_idx / egrid->resolution[2]) % egrid->resolution[1];
1046  r_local_cell[0] = cell_idx / (egrid->resolution[2] * egrid->resolution[1]);
1047 }
1048 
1050  LightProbe *probe,
1051  int cell_idx,
1052  int *r_final_idx,
1053  int r_local_cell[3],
1054  int *r_stride)
1055 {
1056  const int cell_count = probe->grid_resolution_x * probe->grid_resolution_y *
1057  probe->grid_resolution_z;
1058 
1059  /* Add one for level 0 */
1060  int max_lvl = (int)floorf(log2f(
1061  (float)MAX3(probe->grid_resolution_x, probe->grid_resolution_y, probe->grid_resolution_z)));
1062 
1063  int visited_cells = 0;
1064  *r_stride = 0;
1065  *r_final_idx = 0;
1066  r_local_cell[0] = r_local_cell[1] = r_local_cell[2] = 0;
1067  for (int lvl = max_lvl; lvl >= 0; lvl--) {
1068  *r_stride = 1 << lvl;
1069  int prev_stride = *r_stride << 1;
1070  for (int i = 0; i < cell_count; i++) {
1071  *r_final_idx = i;
1072  cell_id_to_grid_loc(egrid, *r_final_idx, r_local_cell);
1073  if (((r_local_cell[0] % *r_stride) == 0) && ((r_local_cell[1] % *r_stride) == 0) &&
1074  ((r_local_cell[2] % *r_stride) == 0)) {
1075  if (!(((r_local_cell[0] % prev_stride) == 0) && ((r_local_cell[1] % prev_stride) == 0) &&
1076  ((r_local_cell[2] % prev_stride) == 0)) ||
1077  ((i == 0) && (lvl == max_lvl))) {
1078  if (visited_cells == cell_idx) {
1079  return;
1080  }
1081 
1082  visited_cells++;
1083  }
1084  }
1085  }
1086  }
1087 
1088  BLI_assert(0);
1089 }
1090 
1091 static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, const int local_cell[3], float r_pos[3])
1092 {
1093  copy_v3_v3(r_pos, egrid->corner);
1094  madd_v3_v3fl(r_pos, egrid->increment_x, local_cell[0]);
1095  madd_v3_v3fl(r_pos, egrid->increment_y, local_cell[1]);
1096  madd_v3_v3fl(r_pos, egrid->increment_z, local_cell[2]);
1097 }
1098 
1099 static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
1100 {
1101  EEVEE_Data *vedata = (EEVEE_Data *)ved;
1103  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
1105  EEVEE_LightGrid *egrid = lbake->grid;
1106  LightProbe *prb = *lbake->probe;
1107  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
1108  LightCache *lcache = scene_eval->eevee.light_cache_data;
1109  int grid_loc[3], sample_id, sample_offset, stride;
1110  float pos[3];
1111  const bool is_last_bounce_sample = ((egrid->offset + lbake->grid_sample) ==
1112  (lbake->total_irr_samples - 1));
1113 
1114  /* No bias for rendering the probe. */
1115  egrid->level_bias = 1.0f;
1116 
1117  /* Use the previous bounce for rendering this bounce. */
1118  SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
1119 
1120  /* TODO: do this once for the whole bake when we have independent DRWManagers.
1121  * WARNING: Some of the things above require this. */
1122  eevee_lightbake_cache_create(vedata, lbake);
1123 
1124  /* Compute sample position */
1125  compute_cell_id(egrid, prb, lbake->grid_sample, &sample_id, grid_loc, &stride);
1126  sample_offset = egrid->offset + sample_id;
1127 
1128  grid_loc_to_world_loc(egrid, grid_loc, pos);
1129 
1130  /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
1131  common_data->spec_toggle = false;
1132  common_data->sss_toggle = false;
1133  common_data->prb_num_planar = 0;
1134  common_data->prb_num_render_cube = 0;
1135  common_data->ray_type = EEVEE_RAY_DIFFUSE;
1136  common_data->ray_depth = lbake->bounce_curr + 1;
1137  if (lbake->bounce_curr == 0) {
1138  common_data->prb_num_render_grid = 0;
1139  }
1140  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1141 
1142  EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, pos, prb->clipsta, prb->clipend);
1143 
1144  /* Restore before filtering. */
1145  SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
1146 
1148  sldata, vedata, lbake->rt_color, lbake->store_fb, sample_offset, prb->intensity);
1149 
1150  if (lbake->bounce_curr == 0) {
1151  /* We only need to filter the visibility for the first bounce. */
1153  vedata,
1154  lbake->rt_depth,
1155  lbake->store_fb,
1156  sample_offset,
1157  prb->clipsta,
1158  prb->clipend,
1159  egrid->visibility_range,
1160  prb->vis_blur,
1161  lbake->vis_res);
1162  }
1163 
1164  /* Update level for progressive update. */
1165  if (is_last_bounce_sample) {
1166  egrid->level_bias = 1.0f;
1167  }
1168  else if (lbake->bounce_curr == 0) {
1169  egrid->level_bias = (float)(stride << 1);
1170  }
1171 
1172  /* Only run this for the last sample of a bounce. */
1173  if (is_last_bounce_sample) {
1174  eevee_lightbake_copy_irradiance(lbake, lcache);
1175  }
1176 
1177  /* If it is the last sample grid sample (and last bounce). */
1178  if ((lbake->bounce_curr == lbake->bounce_len - 1) && (lbake->grid_curr == lbake->grid_len - 1) &&
1179  (lbake->grid_sample == lbake->grid_sample_len - 1)) {
1180  lcache->flag &= ~LIGHTCACHE_UPDATE_GRID;
1181  }
1182 }
1183 
1184 static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
1185 {
1186  EEVEE_Data *vedata = (EEVEE_Data *)ved;
1188  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
1190  Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
1191  LightCache *lcache = scene_eval->eevee.light_cache_data;
1192  EEVEE_LightProbe *eprobe = lbake->cube;
1193  LightProbe *prb = *lbake->probe;
1194  float clamp = scene_eval->eevee.gi_glossy_clamp;
1195  float filter_quality = scene_eval->eevee.gi_filter_quality;
1196 
1197  /* TODO: do this once for the whole bake when we have independent DRWManagers. */
1198  eevee_lightbake_cache_create(vedata, lbake);
1199 
1200  /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
1201  common_data->spec_toggle = false;
1202  common_data->sss_toggle = false;
1203  common_data->prb_num_planar = 0;
1204  common_data->prb_num_render_cube = 0;
1205  common_data->ray_type = EEVEE_RAY_GLOSSY;
1206  common_data->ray_depth = 1;
1207  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1208 
1210  sldata, vedata, lbake->rt_fb, eprobe->position, prb->clipsta, prb->clipend);
1212  vedata,
1213  lbake->rt_color,
1214  lbake->store_fb,
1215  lbake->cube_offset,
1216  prb->intensity,
1217  lcache->mips_len,
1218  filter_quality,
1219  clamp);
1220 
1221  lcache->cube_len += 1;
1222 
1223  /* If it's the last probe. */
1224  if (lbake->cube_offset == lbake->cube_len - 1) {
1225  lcache->flag &= ~LIGHTCACHE_UPDATE_CUBE;
1226  }
1227 }
1228 
1230 {
1231  return mat4_to_scale(grid->mat);
1232 }
1233 
1235 {
1236  return mat4_to_scale(eprb->attenuationmat);
1237 }
1238 
1240 {
1241  float vol_a = eevee_lightbake_grid_influence_volume(grid_a);
1242  float vol_b = eevee_lightbake_grid_influence_volume(grid_b);
1243  return (vol_a < vol_b);
1244 }
1245 
1247 {
1248  float vol_a = eevee_lightbake_cube_influence_volume(prb_a);
1249  float vol_b = eevee_lightbake_cube_influence_volume(prb_b);
1250  return (vol_a < vol_b);
1251 }
1252 
1253 #define SORT_PROBE(elems_type, prbs, elems, elems_len, comp_fn) \
1254  { \
1255  bool sorted = false; \
1256  while (!sorted) { \
1257  sorted = true; \
1258  for (int i = 0; i < (elems_len)-1; i++) { \
1259  if ((comp_fn)((elems) + i, (elems) + i + 1)) { \
1260  SWAP(elems_type, (elems)[i], (elems)[i + 1]); \
1261  SWAP(LightProbe *, (prbs)[i], (prbs)[i + 1]); \
1262  sorted = false; \
1263  } \
1264  } \
1265  } \
1266  } \
1267  ((void)0)
1268 
1270 {
1271  Depsgraph *depsgraph = lbake->depsgraph;
1272  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
1273  LightCache *lcache = scene_eval->eevee.light_cache_data;
1274 
1275  /* At least one for the world */
1276  int grid_len = 1;
1277  int cube_len = 1;
1278  int total_irr_samples = 1;
1279 
1280  /* Convert all lightprobes to tight UBO data from all lightprobes in the scene.
1281  * This allows a large number of probe to be precomputed (even dupli ones). */
1283  const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
1284  if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
1285  continue;
1286  }
1287 
1288  if (ob->type == OB_LIGHTPROBE) {
1289  LightProbe *prb = (LightProbe *)ob->data;
1290 
1291  if (prb->type == LIGHTPROBE_TYPE_GRID) {
1292  lbake->grid_prb[grid_len] = prb;
1293  EEVEE_LightGrid *egrid = &lcache->grid_data[grid_len++];
1294  EEVEE_lightprobes_grid_data_from_object(ob, egrid, &total_irr_samples);
1295  }
1296  else if (prb->type == LIGHTPROBE_TYPE_CUBE && cube_len < EEVEE_PROBE_MAX) {
1297  lbake->cube_prb[cube_len] = prb;
1298  EEVEE_LightProbe *eprobe = &lcache->cube_data[cube_len++];
1300  }
1301  }
1302  }
1304 
1306  lbake->grid_prb + 1,
1307  lcache->grid_data + 1,
1308  lbake->grid_len - 1,
1311  lbake->cube_prb + 1,
1312  lcache->cube_data + 1,
1313  lbake->cube_len - 1,
1315 
1316  lbake->total = lbake->total_irr_samples * lbake->bounce_len + lbake->cube_len;
1317  lbake->done = 0;
1318 }
1319 
1320 void EEVEE_lightbake_update(void *custom_data)
1321 {
1322  EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
1323  Scene *scene_orig = lbake->scene;
1324 
1325  /* If a new light-cache was created, free the old one and reference the new. */
1326  if (lbake->lcache && scene_orig->eevee.light_cache_data != lbake->lcache) {
1327  if (scene_orig->eevee.light_cache_data != NULL) {
1329  }
1330  scene_orig->eevee.light_cache_data = lbake->lcache;
1331  lbake->own_light_cache = false;
1332  }
1333 
1335 
1337 }
1338 
1340  void (*render_callback)(void *ved, void *user_data))
1341 {
1342  if (G.is_break == true || *lbake->stop) {
1343  return false;
1344  }
1345 
1346  Depsgraph *depsgraph = lbake->depsgraph;
1347 
1348  /* TODO: make DRW manager instantiable (and only lock on drawing) */
1350  DRW_custom_pipeline(&draw_engine_eevee_type, depsgraph, render_callback, lbake);
1351  lbake->done += 1;
1352  *lbake->progress = lbake->done / (float)lbake->total;
1353  *lbake->do_update = 1;
1355 
1356  return true;
1357 }
1358 
1359 void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress)
1360 {
1361  EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
1362  Depsgraph *depsgraph = lbake->depsgraph;
1363 
1366 
1368  lbake->stop = stop;
1369  lbake->do_update = do_update;
1370  lbake->progress = progress;
1371 
1372  if (G.background) {
1373  /* Make sure to init GL capabilities before counting probes. */
1376  }
1377 
1378  /* Count lightprobes */
1380 
1381  /* We need to create the FBOs in the right context.
1382  * We cannot do it in the main thread. */
1385 
1386  /* Resource allocation can fail. Early exit in this case. */
1387  if (lbake->lcache->flag & LIGHTCACHE_INVALID) {
1388  *lbake->stop = 1;
1389  *lbake->do_update = 1;
1390  lbake->lcache->flag &= ~LIGHTCACHE_BAKING;
1393  return;
1394  }
1395 
1398 
1399  /* Gather all probes data */
1401 
1402  LightCache *lcache = lbake->lcache;
1403 
1404  /* HACK: Sleep to delay the first rendering operation
1405  * that causes a small freeze (caused by VBO generation)
1406  * because this step is locking at this moment. */
1407  /* TODO: remove this. */
1408  if (lbake->delay) {
1409  PIL_sleep_ms(lbake->delay);
1410  }
1411 
1412  /* Render world irradiance and reflection first */
1413  if (lcache->flag & LIGHTCACHE_UPDATE_WORLD) {
1414  lbake->probe = NULL;
1416  }
1417 
1418  /* Render irradiance grids */
1419  if (lcache->flag & LIGHTCACHE_UPDATE_GRID) {
1420  for (lbake->bounce_curr = 0; lbake->bounce_curr < lbake->bounce_len; lbake->bounce_curr++) {
1421  /* Bypass world, start at 1. */
1422  lbake->probe = lbake->grid_prb + 1;
1423  lbake->grid = lcache->grid_data + 1;
1424  for (lbake->grid_curr = 1; lbake->grid_curr < lbake->grid_len;
1425  lbake->grid_curr++, lbake->probe++, lbake->grid++) {
1426  LightProbe *prb = *lbake->probe;
1427  lbake->grid_sample_len = prb->grid_resolution_x * prb->grid_resolution_y *
1428  prb->grid_resolution_z;
1429  for (lbake->grid_sample = 0; lbake->grid_sample < lbake->grid_sample_len;
1430  ++lbake->grid_sample) {
1432  }
1433  }
1434  }
1435  }
1436 
1437  /* Render reflections */
1438  if (lcache->flag & LIGHTCACHE_UPDATE_CUBE) {
1439  /* Bypass world, start at 1. */
1440  lbake->probe = lbake->cube_prb + 1;
1441  lbake->cube = lcache->cube_data + 1;
1442  for (lbake->cube_offset = 1; lbake->cube_offset < lbake->cube_len;
1443  lbake->cube_offset++, lbake->probe++, lbake->cube++) {
1445  }
1446  }
1447 
1448  /* Read the resulting lighting data to save it to file/disk. */
1453 
1454  lcache->flag |= LIGHTCACHE_BAKED;
1455  lcache->flag &= ~LIGHTCACHE_BAKING;
1456 
1457  /* Assume that if lbake->gl_context is NULL
1458  * we are not running in this in a job, so update
1459  * the scene light-cache pointer before deleting it. */
1460  if (lbake->gl_context == NULL) {
1462  EEVEE_lightbake_update(lbake);
1463  }
1464 
1466 }
1467 
1469  EEVEE_Data *vedata,
1470  const Scene *scene)
1471 {
1472  LightCache *lcache = vedata->stl->g_data->light_cache;
1473  float clamp = scene->eevee.gi_glossy_clamp;
1474  float filter_quality = scene->eevee.gi_filter_quality;
1475 
1476  EEVEE_LightBake lbake = {
1477  .resource_only = true,
1478  };
1479 
1480  /* Create resources. */
1482 
1483  EEVEE_lightbake_cache_init(sldata, vedata, lbake.rt_color, lbake.rt_depth);
1484 
1486  sldata->common_data.ray_depth = 1;
1487  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1488  EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
1490  vedata,
1491  lbake.rt_color,
1492  lbake.store_fb,
1493  0,
1494  1.0f,
1495  lcache->mips_len,
1496  filter_quality,
1497  clamp);
1498 
1500  sldata->common_data.ray_depth = 1;
1501  GPU_uniformbuf_update(sldata->common_ubo, &sldata->common_data);
1502  EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
1503  EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake.rt_color, lbake.store_fb, 0, 1.0f);
1504 
1505  /* Don't hide grids if they are already rendered. */
1506  lcache->grid_len = max_ii(1, lcache->grid_len);
1507  lcache->cube_len = 1;
1508 
1510  lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
1511 
1513 }
1514 
typedef float(TangentPoint)[2]
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
Definition: BKE_object.h:150
int BKE_object_visibility(const struct Object *ob, int dag_eval_mode)
#define BLI_assert(a)
Definition: BLI_assert.h:46
void BLI_endian_switch_float_array(float *val, int size) ATTR_NONNULL(1)
Definition: endian_switch.c:51
void BLI_endian_switch_uint32_array(unsigned int *val, int size) ATTR_NONNULL(1)
Definition: endian_switch.c:41
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:1090
float mat4_to_scale(const float M[4][4])
Definition: math_matrix.c:2185
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])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void BLI_str_format_byte_unit(char dst[15], long long int bytes, bool base_10) ATTR_NONNULL()
Definition: string.c:1132
unsigned int uint
Definition: BLI_sys_types.h:67
void BLI_mutex_free(ThreadMutex *mutex)
Definition: threads.cc:400
ThreadMutex * BLI_mutex_alloc(void)
Definition: threads.cc:393
int BLI_thread_is_main(void)
Definition: threads.cc:207
void BLI_mutex_lock(ThreadMutex *mutex)
Definition: threads.cc:373
void BLI_mutex_unlock(ThreadMutex *mutex)
Definition: threads.cc:378
pthread_mutex_t ThreadMutex
Definition: BLI_threads.h:82
#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:5143
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr)
Definition: writefile.c:1489
#define TIP_(msgid)
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:267
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:46
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:295
void DEG_evaluate_on_framechange(Depsgraph *graph, float frame)
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:834
Object groups, one object can be in many groups at once.
@ LIGHTCACHETEX_FLOAT
@ LIGHTCACHETEX_BYTE
@ LIGHTCACHETEX_UINT
@ 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_TYPE_CUBE
@ LIGHTPROBE_TYPE_GRID
#define LIGHTCACHE_STATIC_VERSION
@ LIGHTCACHE_TYPE_STATIC
@ LIGHTPROBE_FLAG_INVERT_GROUP
@ OB_LIGHTPROBE
@ SCE_EEVEE_SHADOW_HIGH_BITDEPTH
DRWTextureFlag
Definition: DRW_render.h:139
@ DRW_TEX_MIPMAP
Definition: DRW_render.h:143
@ DRW_TEX_FILTER
Definition: DRW_render.h:140
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:183
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:171
void GPU_context_discard(GPUContext *)
Definition: gpu_context.cc:110
GPUContext * GPU_context_create(void *ghost_window)
Definition: gpu_context.cc:93
void GPU_context_main_unlock(void)
Definition: gpu_context.cc:176
struct GPUFrameBuffer GPUFrameBuffer
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:297
void GPU_texture_update_mipmap(GPUTexture *tex, int miplvl, eGPUDataFormat gpu_data_format, const void *pixels)
Definition: gpu_texture.cc:406
int GPU_texture_height(const GPUTexture *tex)
Definition: gpu_texture.cc:607
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter)
Definition: gpu_texture.cc:527
int GPU_texture_width(const GPUTexture *tex)
Definition: gpu_texture.cc:602
void * GPU_texture_read(GPUTexture *tex, eGPUDataFormat data_format, int miplvl)
Definition: gpu_texture.cc:432
@ GPU_DATA_10_11_11_REV
Definition: GPU_texture.h:176
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:174
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:171
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
Definition: gpu_texture.cc:688
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:444
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter)
Definition: gpu_texture.cc:518
@ GPU_DEPTH_COMPONENT24
Definition: GPU_texture.h:166
@ GPU_R11F_G11F_B10F
Definition: GPU_texture.h:118
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:329
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
#define MEM_SAFE_FREE(v)
Platform independent time functions.
@ WM_JOB_EXCL_RENDER
Definition: WM_api.h:1338
@ WM_JOB_PROGRESS
Definition: WM_api.h:1339
@ WM_JOB_PRIORITY
Definition: WM_api.h:1337
@ WM_JOB_TYPE_LIGHT_BAKE
Definition: WM_api.h:1369
@ WM_JOB_TYPE_RENDER
Definition: WM_api.h:1349
#define NC_SCENE
Definition: WM_types.h:328
#define NA_EDITED
Definition: WM_types.h:523
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
const Depsgraph * depsgraph
void * user_data
void DRW_curves_update(void)
Definition: draw_curves.cc:414
void DRW_render_viewport_size_set(const int size[2])
Definition: draw_manager.c:280
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(const DRWView *view)
void DRW_draw_pass(DRWPass *pass)
void DRW_view_set_active(const DRWView *view)
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:259
void EEVEE_view_layer_data_free(void *storage)
Definition: eevee_data.c:191
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:56
void EEVEE_effects_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
DrawEngineType draw_engine_eevee_type
Definition: eevee_engine.c:618
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img GPU_RGBA16F
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:230
void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
Definition: eevee_lights.c:192
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:182
void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
#define EEVEE_PROBE_MAX
Definition: eevee_private.h:73
#define EEVEE_RAY_DIFFUSE
#define EEVEE_RAY_GLOSSY
void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata)
Definition: eevee_shadows.c:26
@ 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)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:26
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
#define ceilf(x)
Definition: metal/compat.h:225
#define floorf(x)
Definition: metal/compat.h:224
T clamp(const T &a, const T &min, const T &max)
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:121
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:57
void PIL_sleep_ms(int ms)
Definition: time.c:84
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:351
void * WM_jobs_customdata_get(wmJob *wm_job)
Definition: wm_jobs.c:315
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition: wm_jobs.c:214
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:323
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:339
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:184
void * WM_opengl_context_create(void)
Definition: wm_window.c:2353
void wm_window_reset_drawable(void)
Definition: wm_window.c:1049
void WM_opengl_context_dispose(void *context)
Definition: wm_window.c:2374