2 * Copyright 2016, Blender Foundation.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Blender Institute
22 /** \file eevee_lightcache.c
23 * \ingroup draw_engine
25 * Eevee's indirect lighting cache.
28 #include "DRW_render.h"
30 #include "BKE_global.h"
31 #include "BKE_blender.h"
33 #include "BLI_threads.h"
35 #include "DEG_depsgraph_build.h"
36 #include "DEG_depsgraph_query.h"
38 #include "BKE_object.h"
40 #include "DNA_collection_types.h"
41 #include "DNA_lightprobe_types.h"
45 #include "eevee_lightcache.h"
46 #include "eevee_private.h"
48 #include "GPU_context.h"
53 #include "wm_window.h"
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_CUBEMAP)
60 #define IRRADIANCE_SAMPLE_SIZE_X 8
61 #define IRRADIANCE_SAMPLE_SIZE_Y 8
62 #elif defined(IRRADIANCE_HL2)
63 #define IRRADIANCE_SAMPLE_SIZE_X 4 /* 3 in reality */
64 #define IRRADIANCE_SAMPLE_SIZE_Y 2
67 #ifdef IRRADIANCE_SH_L2
68 /* we need a signed format for Spherical Harmonics */
69 # define IRRADIANCE_FORMAT GPU_RGBA16F
71 # define IRRADIANCE_FORMAT GPU_RGBA8
74 #define IRRADIANCE_MAX_POOL_LAYER 256 /* OpenGL 3.3 core requirement, can be extended but it's already very big */
75 #define IRRADIANCE_MAX_POOL_SIZE 1024
76 #define MAX_IRRADIANCE_SAMPLES \
77 (IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_X) * \
78 (IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_Y)
80 /* TODO should be replace by a more elegant alternative. */
81 extern void DRW_opengl_context_enable(void);
82 extern void DRW_opengl_context_disable(void);
84 extern void DRW_opengl_render_context_enable(void *re_gl_context);
85 extern void DRW_opengl_render_context_disable(void *re_gl_context);
86 extern void DRW_gawain_render_context_enable(void *re_gpu_context);
87 extern void DRW_gawain_render_context_disable(void *re_gpu_context);
89 typedef struct EEVEE_LightBake {
91 ViewLayer *view_layer;
92 ViewLayer *view_layer_input;
96 EEVEE_ViewLayerData *sldata;
98 LightProbe **probe; /* Current probe being rendered. */
99 GPUTexture *rt_color; /* Target cube color texture. */
100 GPUTexture *rt_depth; /* Target cube depth texture. */
101 GPUFrameBuffer *rt_fb[6]; /* Target cube framebuffers. */
102 GPUFrameBuffer *store_fb; /* Storage framebuffer. */
103 int rt_res; /* Cube render target resolution. */
106 int layer; /* Target layer to store the data to. */
107 float samples_ct, invsamples_ct; /* Sample count for the convolution. */
108 float lod_factor; /* Sampling bias during convolution step. */
109 float lod_max; /* Max cubemap LOD to sample when convolving. */
110 int cube_len, grid_len; /* Number of probes to render + world probe. */
112 /* Irradiance grid */
113 EEVEE_LightGrid *grid; /* Current probe being rendered (UBO data). */
114 int irr_cube_res; /* Target cubemap at MIP 0. */
115 int irr_size[3]; /* Size of the irradiance texture. */
116 int total_irr_samples; /* Total for all grids */
117 int grid_sample; /* Nth sample of the current grid being rendered. */
118 int grid_sample_len; /* Total number of samples for the current grid. */
119 int grid_curr; /* Nth grid in the cache being rendered. */
120 int bounce_curr, bounce_len; /* The current light bounce being evaluated. */
121 float vis_res; /* Resolution of the Visibility shadowmap. */
122 GPUTexture *grid_prev; /* Result of previous light bounce. */
123 LightProbe **grid_prb; /* Pointer to the id.data of the probe object. */
125 /* Reflection probe */
126 EEVEE_LightProbe *cube; /* Current probe being rendered (UBO data). */
127 int ref_cube_res; /* Target cubemap at MIP 0. */
128 int cube_offset; /* Index of the current cube. */
129 LightProbe **cube_prb; /* Pointer to the id.data of the probe object. */
132 struct GPUTexture *dummy_color, *dummy_depth;
133 struct GPUTexture *dummy_layer_color;
135 int total, done; /* to compute progress */
136 short *stop, *do_update;
139 bool resource_only; /* For only handling the resources. */
141 bool own_light_cache; /* If the lightcache was created for baking, it's first owned by the baker. */
142 int delay; /* ms. delay the start of the baking to not slowdown interactions (TODO remove) */
144 void *gl_context, *gpu_context; /* If running in parallel (in a separate thread), use this context. */
149 /* -------------------------------------------------------------------- */
151 /** \name Light Cache
154 /* Return memory footprint in bytes. */
155 static uint eevee_lightcache_memsize_get(LightCache *lcache)
158 if (lcache->grid_tx.data) {
159 size += MEM_allocN_len(lcache->grid_tx.data);
161 if (lcache->cube_tx.data) {
162 size += MEM_allocN_len(lcache->cube_tx.data);
163 for (int mip = 0; mip < lcache->mips_len; ++mip) {
164 size += MEM_allocN_len(lcache->cube_mips[mip].data);
170 static int eevee_lightcache_irradiance_sample_count(LightCache *lcache)
172 int total_irr_samples = 0;
174 for (int i = 1; i < lcache->grid_len; ++i) {
175 EEVEE_LightGrid *egrid = lcache->grid_data + i;
176 total_irr_samples += egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2];
178 return total_irr_samples;
181 void EEVEE_lightcache_info_update(SceneEEVEE *eevee)
183 LightCache *lcache = eevee->light_cache;
185 if (lcache != NULL) {
186 if (lcache->flag & LIGHTCACHE_BAKING) {
187 BLI_strncpy(eevee->light_cache_info, IFACE_("Baking light cache"), sizeof(eevee->light_cache_info));
191 char formatted_mem[15];
192 BLI_str_format_byte_unit(formatted_mem, eevee_lightcache_memsize_get(lcache), true);
194 int irr_samples = eevee_lightcache_irradiance_sample_count(lcache);
196 BLI_snprintf(eevee->light_cache_info, sizeof(eevee->light_cache_info), IFACE_("%d Ref. Cubemaps, %d Irr. Samples (%s in memory)"), lcache->cube_len - 1, irr_samples, formatted_mem);
199 BLI_strncpy(eevee->light_cache_info, IFACE_("No light cache in this scene"), sizeof(eevee->light_cache_info));
203 static void irradiance_pool_size_get(int visibility_size, int total_samples, int r_size[3])
205 /* Compute how many irradiance samples we can store per visibility sample. */
206 int irr_per_vis = (visibility_size / IRRADIANCE_SAMPLE_SIZE_X) *
207 (visibility_size / IRRADIANCE_SAMPLE_SIZE_Y);
209 /* The irradiance itself take one layer, hence the +1 */
210 int layer_ct = MIN2(irr_per_vis + 1, IRRADIANCE_MAX_POOL_LAYER);
212 int texel_ct = (int)ceilf((float)total_samples / (float)(layer_ct - 1));
213 r_size[0] = visibility_size * max_ii(1, min_ii(texel_ct, (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
214 r_size[1] = visibility_size * max_ii(1, (texel_ct / (IRRADIANCE_MAX_POOL_SIZE / visibility_size)));
215 r_size[2] = layer_ct;
218 static bool EEVEE_lightcache_validate(
219 const LightCache *light_cache,
223 const int irr_size[3])
226 /* See if we need the same amount of texture space. */
227 if ((irr_size[0] == light_cache->grid_tx.tex_size[0]) &&
228 (irr_size[1] == light_cache->grid_tx.tex_size[1]) &&
229 (irr_size[2] == light_cache->grid_tx.tex_size[2]) &&
230 (grid_len == light_cache->grid_len))
232 int mip_len = (int)(floorf(log2f(cube_res)) - MIN_CUBE_LOD_LEVEL);
233 if ((cube_res == light_cache->cube_tx.tex_size[0]) &&
234 (cube_len == light_cache->cube_tx.tex_size[2]) &&
235 (mip_len == light_cache->mips_len))
244 LightCache *EEVEE_lightcache_create(
249 const int irr_size[3])
251 LightCache *light_cache = MEM_callocN(sizeof(LightCache), "LightCache");
253 light_cache->cube_data = MEM_callocN(sizeof(EEVEE_LightProbe) * cube_len, "EEVEE_LightProbe");
254 light_cache->grid_data = MEM_callocN(sizeof(EEVEE_LightGrid) * grid_len, "EEVEE_LightGrid");
256 light_cache->grid_tx.tex = DRW_texture_create_2D_array(irr_size[0], irr_size[1], irr_size[2], IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
257 light_cache->grid_tx.tex_size[0] = irr_size[0];
258 light_cache->grid_tx.tex_size[1] = irr_size[1];
259 light_cache->grid_tx.tex_size[2] = irr_size[2];
261 light_cache->cube_tx.tex = DRW_texture_create_2D_array(cube_size, cube_size, cube_len, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
262 light_cache->cube_tx.tex_size[0] = cube_size;
263 light_cache->cube_tx.tex_size[1] = cube_size;
264 light_cache->cube_tx.tex_size[2] = cube_len;
266 light_cache->mips_len = (int)(floorf(log2f(cube_size)) - MIN_CUBE_LOD_LEVEL);
267 light_cache->vis_res = vis_size;
268 light_cache->ref_res = cube_size;
270 light_cache->cube_mips = MEM_callocN(sizeof(LightCacheTexture) * light_cache->mips_len, "LightCacheTexture");
272 for (int mip = 0; mip < light_cache->mips_len; ++mip) {
273 GPU_texture_get_mipmap_size(light_cache->cube_tx.tex, mip + 1, light_cache->cube_mips[mip].tex_size);
276 light_cache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
281 void EEVEE_lightcache_load(LightCache *lcache)
283 if (lcache->grid_tx.tex == NULL && lcache->grid_tx.data) {
284 lcache->grid_tx.tex = GPU_texture_create_nD(
285 lcache->grid_tx.tex_size[0],
286 lcache->grid_tx.tex_size[1],
287 lcache->grid_tx.tex_size[2],
289 lcache->grid_tx.data,
291 GPU_DATA_UNSIGNED_BYTE,
295 GPU_texture_bind(lcache->grid_tx.tex, 0);
296 GPU_texture_filter_mode(lcache->grid_tx.tex, true);
297 GPU_texture_unbind(lcache->grid_tx.tex);
300 if (lcache->cube_tx.tex == NULL && lcache->cube_tx.data) {
301 lcache->cube_tx.tex = GPU_texture_create_nD(
302 lcache->cube_tx.tex_size[0],
303 lcache->cube_tx.tex_size[1],
304 lcache->cube_tx.tex_size[2],
306 lcache->cube_tx.data,
308 GPU_DATA_10_11_11_REV,
312 GPU_texture_bind(lcache->cube_tx.tex, 0);
313 GPU_texture_mipmap_mode(lcache->cube_tx.tex, true, true);
314 for (int mip = 0; mip < lcache->mips_len; ++mip) {
315 GPU_texture_add_mipmap(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1, lcache->cube_mips[mip].data);
317 GPU_texture_unbind(lcache->cube_tx.tex);
321 static void eevee_lightbake_readback_irradiance(LightCache *lcache)
323 MEM_SAFE_FREE(lcache->grid_tx.data);
324 lcache->grid_tx.data = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_UNSIGNED_BYTE, 0);
325 lcache->grid_tx.data_type = LIGHTCACHETEX_BYTE;
326 lcache->grid_tx.components = 4;
329 static void eevee_lightbake_readback_reflections(LightCache *lcache)
331 MEM_SAFE_FREE(lcache->cube_tx.data);
332 lcache->cube_tx.data = GPU_texture_read(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, 0);
333 lcache->cube_tx.data_type = LIGHTCACHETEX_UINT;
334 lcache->cube_tx.components = 1;
336 for (int mip = 0; mip < lcache->mips_len; ++mip) {
337 LightCacheTexture *cube_mip = lcache->cube_mips + mip;
338 MEM_SAFE_FREE(cube_mip->data);
339 GPU_texture_get_mipmap_size(lcache->cube_tx.tex, mip + 1, cube_mip->tex_size);
341 cube_mip->data = GPU_texture_read(lcache->cube_tx.tex, GPU_DATA_10_11_11_REV, mip + 1);
342 cube_mip->data_type = LIGHTCACHETEX_UINT;
343 cube_mip->components = 1;
347 void EEVEE_lightcache_free(LightCache *lcache)
349 DRW_TEXTURE_FREE_SAFE(lcache->cube_tx.tex);
350 MEM_SAFE_FREE(lcache->cube_tx.data);
351 DRW_TEXTURE_FREE_SAFE(lcache->grid_tx.tex);
352 MEM_SAFE_FREE(lcache->grid_tx.data);
354 if (lcache->cube_mips) {
355 for (int i = 0; i < lcache->mips_len; ++i) {
356 MEM_SAFE_FREE(lcache->cube_mips[i].data);
358 MEM_SAFE_FREE(lcache->cube_mips);
361 MEM_SAFE_FREE(lcache->cube_data);
362 MEM_SAFE_FREE(lcache->grid_data);
369 /* -------------------------------------------------------------------- */
371 /** \name Light Bake Context
374 static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
376 if (lbake->gl_context) {
377 DRW_opengl_render_context_enable(lbake->gl_context);
378 if (lbake->gpu_context == NULL) {
379 lbake->gpu_context = GPU_context_create();
381 DRW_gawain_render_context_enable(lbake->gpu_context);
384 DRW_opengl_context_enable();
388 static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
390 if (lbake->gl_context) {
391 DRW_gawain_render_context_disable(lbake->gpu_context);
392 DRW_opengl_render_context_disable(lbake->gl_context);
395 DRW_opengl_context_disable();
402 /* -------------------------------------------------------------------- */
404 /** \name Light Bake Job
407 static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
409 Depsgraph *depsgraph = lbake->depsgraph;
411 /* At least one of each for the world */
412 lbake->grid_len = lbake->cube_len = lbake->total_irr_samples = 1;
414 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
416 const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
417 if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
421 if (ob->type == OB_LIGHTPROBE) {
422 LightProbe *prb = (LightProbe *)ob->data;
424 if (prb->type == LIGHTPROBE_TYPE_GRID) {
425 lbake->total_irr_samples += prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
428 else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
433 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
436 static void eevee_lightbake_create_render_target(EEVEE_LightBake *lbake, int rt_res)
438 lbake->rt_depth = DRW_texture_create_cube(rt_res, GPU_DEPTH_COMPONENT24, 0, NULL);
439 lbake->rt_color = DRW_texture_create_cube(rt_res, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
441 for (int i = 0; i < 6; ++i) {
442 GPU_framebuffer_ensure_config(&lbake->rt_fb[i], {
443 GPU_ATTACHMENT_TEXTURE_CUBEFACE(lbake->rt_depth, i),
444 GPU_ATTACHMENT_TEXTURE_CUBEFACE(lbake->rt_color, i)
448 GPU_framebuffer_ensure_config(&lbake->store_fb, {
454 static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
456 Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
457 SceneEEVEE *eevee = &scene_eval->eevee;
459 lbake->bounce_len = eevee->gi_diffuse_bounces;
460 lbake->vis_res = eevee->gi_visibility_resolution;
461 lbake->rt_res = eevee->gi_cubemap_resolution;
463 irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);
465 lbake->ref_cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(lbake->rt_res);
467 lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_len, "EEVEE Cube visgroup ptr");
468 lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_len, "EEVEE Grid visgroup ptr");
470 lbake->grid_prev = DRW_texture_create_2D_array(
471 lbake->irr_size[0], lbake->irr_size[1], lbake->irr_size[2],
472 IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
474 /* Ensure Light Cache is ready to accept new data. If not recreate one.
475 * WARNING: All the following must be threadsafe. It's currently protected
476 * by the DRW mutex. */
477 lbake->lcache = eevee->light_cache;
479 /* TODO validate irradiance and reflection cache independently... */
480 if (!EEVEE_lightcache_validate(
481 lbake->lcache, lbake->cube_len, lbake->ref_cube_res, lbake->grid_len, lbake->irr_size))
483 eevee->light_cache = lbake->lcache = NULL;
486 if (lbake->lcache == NULL) {
487 lbake->lcache = EEVEE_lightcache_create(
493 lbake->lcache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
494 lbake->lcache->vis_res = lbake->vis_res;
495 lbake->own_light_cache = true;
497 eevee->light_cache = lbake->lcache;
500 EEVEE_lightcache_load(eevee->light_cache);
502 lbake->lcache->flag |= LIGHTCACHE_BAKING;
503 lbake->lcache->cube_len = 1;
506 wmJob *EEVEE_lightbake_job_create(
507 struct wmWindowManager *wm, struct wmWindow *win, struct Main *bmain,
508 struct ViewLayer *view_layer, struct Scene *scene, int delay)
510 EEVEE_LightBake *lbake = NULL;
512 /* only one render job at a time */
513 if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER))
516 wmJob *wm_job = WM_jobs_get(wm, win, scene, "Bake Lighting",
517 WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_LIGHT_BAKE);
519 /* If job exists do not recreate context and depsgraph. */
520 EEVEE_LightBake *old_lbake = (EEVEE_LightBake *)WM_jobs_customdata_get(wm_job);
522 if (old_lbake && (old_lbake->view_layer_input == view_layer) && (old_lbake->bmain == bmain)) {
523 lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
524 /* Cannot reuse depsgraph for now because we cannot get the update from the
525 * main database directly. TODO reuse depsgraph and only update positions. */
526 /* lbake->depsgraph = old_lbake->depsgraph; */
527 lbake->depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
529 lbake->mutex = BLI_mutex_alloc();
531 BLI_mutex_lock(old_lbake->mutex);
532 old_lbake->own_resources = false;
534 lbake->scene = scene;
535 lbake->bmain = bmain;
536 lbake->view_layer_input = view_layer;
537 lbake->gl_context = old_lbake->gl_context;
538 lbake->own_resources = true;
539 lbake->delay = delay;
541 if (lbake->gl_context == NULL) {
542 lbake->gl_context = WM_opengl_context_create();
543 wm_window_reset_drawable();
546 if (old_lbake->stop != NULL) {
547 *old_lbake->stop = 1;
549 BLI_mutex_unlock(old_lbake->mutex);
552 lbake = EEVEE_lightbake_job_data_alloc(bmain, view_layer, scene, true);
553 lbake->delay = delay;
556 WM_jobs_customdata_set(wm_job, lbake, EEVEE_lightbake_job_data_free);
557 WM_jobs_timer(wm_job, 0.4, NC_SCENE | NA_EDITED, 0);
558 WM_jobs_callbacks(wm_job, EEVEE_lightbake_job, NULL, EEVEE_lightbake_update, EEVEE_lightbake_update);
565 /* MUST run on the main thread. */
566 void *EEVEE_lightbake_job_data_alloc(
567 struct Main *bmain, struct ViewLayer *view_layer, struct Scene *scene, bool run_as_job)
569 BLI_assert(BLI_thread_is_main());
571 EEVEE_LightBake *lbake = MEM_callocN(sizeof(EEVEE_LightBake), "EEVEE_LightBake");
573 lbake->depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
574 lbake->scene = scene;
575 lbake->bmain = bmain;
576 lbake->view_layer_input = view_layer;
577 lbake->own_resources = true;
578 lbake->own_light_cache = false;
579 lbake->mutex = BLI_mutex_alloc();
582 lbake->gl_context = WM_opengl_context_create();
583 wm_window_reset_drawable();
589 void EEVEE_lightbake_job_data_free(void *custom_data)
591 EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
595 /* TODO reuse depsgraph. */
596 /* if (lbake->own_resources) { */
597 DEG_graph_free(lbake->depsgraph);
600 MEM_SAFE_FREE(lbake->cube_prb);
601 MEM_SAFE_FREE(lbake->grid_prb);
603 BLI_mutex_free(lbake->mutex);
608 static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
610 if (!lbake->resource_only) {
611 BLI_mutex_lock(lbake->mutex);
614 if (lbake->gl_context) {
615 DRW_opengl_render_context_enable(lbake->gl_context);
616 DRW_gawain_render_context_enable(lbake->gpu_context);
618 else if (!lbake->resource_only) {
619 DRW_opengl_context_enable();
622 /* XXX Free the resources contained in the viewlayer data
623 * to be able to free the context before deleting the depsgraph. */
625 EEVEE_view_layer_data_free(lbake->sldata);
628 DRW_TEXTURE_FREE_SAFE(lbake->rt_depth);
629 DRW_TEXTURE_FREE_SAFE(lbake->rt_color);
630 DRW_TEXTURE_FREE_SAFE(lbake->grid_prev);
631 GPU_FRAMEBUFFER_FREE_SAFE(lbake->store_fb);
632 for (int i = 0; i < 6; ++i) {
633 GPU_FRAMEBUFFER_FREE_SAFE(lbake->rt_fb[i]);
636 if (lbake->gpu_context) {
637 DRW_gawain_render_context_disable(lbake->gpu_context);
638 DRW_gawain_render_context_enable(lbake->gpu_context);
639 GPU_context_discard(lbake->gpu_context);
642 if (lbake->gl_context && lbake->own_resources) {
643 /* Delete the baking context. */
644 DRW_opengl_render_context_disable(lbake->gl_context);
645 WM_opengl_context_dispose(lbake->gl_context);
646 lbake->gpu_context = NULL;
647 lbake->gl_context = NULL;
649 else if (lbake->gl_context) {
650 DRW_opengl_render_context_disable(lbake->gl_context);
652 else if (!lbake->resource_only) {
653 DRW_opengl_context_disable();
656 if (!lbake->resource_only) {
657 BLI_mutex_unlock(lbake->mutex);
661 /* Cache as in draw cache not light cache. */
662 static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lbake)
664 EEVEE_TextureList *txl = vedata->txl;
665 EEVEE_StorageList *stl = vedata->stl;
666 EEVEE_FramebufferList *fbl = vedata->fbl;
667 EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
668 Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
669 lbake->sldata = sldata;
671 /* Disable all effects BUT high bitdepth shadows. */
672 scene_eval->eevee.flag &= SCE_EEVEE_SHADOW_HIGH_BITDEPTH;
673 scene_eval->eevee.taa_samples = 1;
674 scene_eval->eevee.gi_irradiance_smoothing = 0.0f;
676 stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
677 stl->g_data->background_alpha = 1.0f;
679 /* XXX TODO remove this. This is in order to make the init functions work. */
680 DRWMatrixState dummy_mats = {{{{{0}}}}};
681 DRW_viewport_matrix_override_set_all(&dummy_mats);
683 if (sldata->common_ubo == NULL) {
684 sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data), &sldata->common_data);
686 if (sldata->clip_ubo == NULL) {
687 sldata->clip_ubo = DRW_uniformbuffer_create(sizeof(sldata->clip_data), &sldata->clip_data);
690 /* HACK: set txl->color but unset it before Draw Manager frees it. */
691 txl->color = lbake->rt_color;
692 int viewport_size[2] = {
693 GPU_texture_width(txl->color),
694 GPU_texture_height(txl->color)
696 DRW_render_viewport_size_set(viewport_size);
698 EEVEE_effects_init(sldata, vedata, NULL, true);
699 EEVEE_materials_init(sldata, stl, fbl);
700 EEVEE_lights_init(sldata);
701 EEVEE_lightprobes_init(sldata, vedata);
703 EEVEE_effects_cache_init(sldata, vedata);
704 EEVEE_materials_cache_init(sldata, vedata);
705 EEVEE_lights_cache_init(sldata, vedata);
706 EEVEE_lightprobes_cache_init(sldata, vedata);
708 EEVEE_lightbake_cache_init(sldata, vedata, lbake->rt_color, lbake->rt_depth);
711 EEVEE_LightProbesInfo *pinfo = sldata->probes;
712 LightProbe *prb = *lbake->probe;
713 pinfo->vis_data.collection = prb->visibility_grp;
714 pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP;
715 pinfo->vis_data.cached = false;
717 DRW_render_object_iter(vedata, NULL, lbake->depsgraph, EEVEE_render_cache);
719 EEVEE_materials_cache_finish(vedata);
720 EEVEE_lights_cache_finish(sldata, vedata);
721 EEVEE_lightprobes_cache_finish(sldata, vedata);
725 DRW_render_instance_buffer_finish();
729 static void eevee_lightbake_copy_irradiance(EEVEE_LightBake *lbake, LightCache *lcache)
731 DRW_TEXTURE_FREE_SAFE(lbake->grid_prev);
733 /* Copy texture by reading back and reuploading it. */
734 float *tex = GPU_texture_read(lcache->grid_tx.tex, GPU_DATA_FLOAT, 0);
735 lbake->grid_prev = DRW_texture_create_2D_array(lbake->irr_size[0], lbake->irr_size[1], lbake->irr_size[2],
736 IRRADIANCE_FORMAT, DRW_TEX_FILTER, tex);
741 static void eevee_lightbake_render_world_sample(void *ved, void *user_data)
743 EEVEE_Data *vedata = (EEVEE_Data *)ved;
744 EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
745 EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
746 Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
747 LightCache *lcache = scene_eval->eevee.light_cache;
748 float clamp = scene_eval->eevee.gi_glossy_clamp;
749 float filter_quality = scene_eval->eevee.gi_filter_quality;
751 /* TODO do this once for the whole bake when we have independent DRWManagers. */
752 eevee_lightbake_cache_create(vedata, lbake);
754 sldata->common_data.ray_type = EEVEE_RAY_GLOSSY;
755 sldata->common_data.ray_depth = 1;
756 DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
757 EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
758 EEVEE_lightbake_filter_glossy(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f, lcache->mips_len, filter_quality, clamp);
760 sldata->common_data.ray_type = EEVEE_RAY_DIFFUSE;
761 sldata->common_data.ray_depth = 1;
762 DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
763 EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb);
764 EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f);
766 /* Clear the cache to avoid white values in the grid. */
767 GPU_framebuffer_texture_attach(lbake->store_fb, lbake->grid_prev, 0, 0);
768 GPU_framebuffer_bind(lbake->store_fb);
769 /* Clear to 1.0f for visibility. */
770 GPU_framebuffer_clear_color(lbake->store_fb, ((float[4]){1.0f, 1.0f, 1.0f, 1.0f}));
771 DRW_draw_pass(vedata->psl->probe_grid_fill);
773 SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
775 /* Make a copy for later. */
776 eevee_lightbake_copy_irradiance(lbake, lcache);
778 lcache->cube_len = 1;
779 lcache->grid_len = lbake->grid_len;
781 lcache->flag |= LIGHTCACHE_CUBE_READY | LIGHTCACHE_GRID_READY;
782 lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
785 static void cell_id_to_grid_loc(EEVEE_LightGrid *egrid, int cell_idx, int r_local_cell[3])
787 /* Keep in sync with lightprobe_grid_display_vert */
788 r_local_cell[2] = cell_idx % egrid->resolution[2];
789 r_local_cell[1] = (cell_idx / egrid->resolution[2]) % egrid->resolution[1];
790 r_local_cell[0] = cell_idx / (egrid->resolution[2] * egrid->resolution[1]);
793 static void compute_cell_id(
794 EEVEE_LightGrid *egrid, LightProbe *probe,
795 int cell_idx, int *r_final_idx, int r_local_cell[3], int *r_stride)
797 const int cell_count = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z;
799 /* Add one for level 0 */
800 int max_lvl = (int)floorf(log2f((float)MAX3(probe->grid_resolution_x,
801 probe->grid_resolution_y,
802 probe->grid_resolution_z)));
804 int visited_cells = 0;
807 r_local_cell[0] = r_local_cell[1] = r_local_cell[2] = 0;
808 for (int lvl = max_lvl; lvl >= 0; --lvl) {
809 *r_stride = 1 << lvl;
810 int prev_stride = *r_stride << 1;
811 for (int i = 0; i < cell_count; ++i) {
813 cell_id_to_grid_loc(egrid, *r_final_idx, r_local_cell);
814 if (((r_local_cell[0] % *r_stride) == 0) &&
815 ((r_local_cell[1] % *r_stride) == 0) &&
816 ((r_local_cell[2] % *r_stride) == 0))
818 if (!(((r_local_cell[0] % prev_stride) == 0) &&
819 ((r_local_cell[1] % prev_stride) == 0) &&
820 ((r_local_cell[2] % prev_stride) == 0)) ||
821 ((i == 0) && (lvl == max_lvl)))
823 if (visited_cells == cell_idx) {
837 static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, int local_cell[3], float r_pos[3])
839 copy_v3_v3(r_pos, egrid->corner);
840 madd_v3_v3fl(r_pos, egrid->increment_x, local_cell[0]);
841 madd_v3_v3fl(r_pos, egrid->increment_y, local_cell[1]);
842 madd_v3_v3fl(r_pos, egrid->increment_z, local_cell[2]);
845 static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
847 EEVEE_Data *vedata = (EEVEE_Data *)ved;
848 EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
849 EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
850 EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
851 EEVEE_LightGrid *egrid = lbake->grid;
852 LightProbe *prb = *lbake->probe;
853 Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
854 LightCache *lcache = scene_eval->eevee.light_cache;
855 int grid_loc[3], sample_id, sample_offset, stride;
857 const bool is_last_bounce_sample = ((egrid->offset + lbake->grid_sample) == (lbake->total_irr_samples - 1));
859 /* No bias for rendering the probe. */
860 egrid->level_bias = 1.0f;
862 /* Use the previous bounce for rendering this bounce. */
863 SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
865 /* TODO do this once for the whole bake when we have independent DRWManagers.
866 * Warning: Some of the things above require this. */
867 eevee_lightbake_cache_create(vedata, lbake);
869 /* Compute sample position */
870 compute_cell_id(egrid, prb, lbake->grid_sample, &sample_id, grid_loc, &stride);
871 sample_offset = egrid->offset + sample_id;
873 grid_loc_to_world_loc(egrid, grid_loc, pos);
875 /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
876 common_data->spec_toggle = false;
877 common_data->prb_num_planar = 0;
878 common_data->prb_num_render_cube = 0;
879 common_data->ray_type = EEVEE_RAY_DIFFUSE;
880 common_data->ray_depth = lbake->bounce_curr + 1;
881 if (lbake->bounce_curr == 0) {
882 common_data->prb_num_render_grid = 0;
884 DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
886 EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, pos, prb->clipsta, prb->clipend);
888 /* Restore before filtering. */
889 SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx.tex);
891 EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, sample_offset, prb->intensity);
893 if (lbake->bounce_curr == 0) {
894 /* We only need to filter the visibility for the first bounce. */
895 EEVEE_lightbake_filter_visibility(
896 sldata, vedata, lbake->rt_depth, lbake->store_fb, sample_offset,
897 prb->clipsta, prb->clipend, egrid->visibility_range,
898 prb->vis_blur, lbake->vis_res);
901 /* Update level for progressive update. */
902 if (is_last_bounce_sample) {
903 egrid->level_bias = 1.0f;
905 else if (lbake->bounce_curr == 0) {
906 egrid->level_bias = (float)(stride << 1);
909 /* Only run this for the last sample of a bounce. */
910 if (is_last_bounce_sample) {
911 eevee_lightbake_copy_irradiance(lbake, lcache);
914 /* If it is the last sample grid sample (and last bounce). */
915 if ((lbake->bounce_curr == lbake->bounce_len - 1) &&
916 (lbake->grid_curr == lbake->grid_len - 1) &&
917 (lbake->grid_sample == lbake->grid_sample_len - 1))
919 lcache->flag &= ~LIGHTCACHE_UPDATE_GRID;
923 static void eevee_lightbake_render_probe_sample(void *ved, void *user_data)
925 EEVEE_Data *vedata = (EEVEE_Data *)ved;
926 EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
927 EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
928 EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
929 Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
930 LightCache *lcache = scene_eval->eevee.light_cache;
931 EEVEE_LightProbe *eprobe = lbake->cube;
932 LightProbe *prb = *lbake->probe;
933 float clamp = scene_eval->eevee.gi_glossy_clamp;
934 float filter_quality = scene_eval->eevee.gi_filter_quality;
936 /* TODO do this once for the whole bake when we have independent DRWManagers. */
937 eevee_lightbake_cache_create(vedata, lbake);
939 /* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
940 common_data->spec_toggle = false;
941 common_data->prb_num_planar = 0;
942 common_data->prb_num_render_cube = 0;
943 common_data->ray_type = EEVEE_RAY_GLOSSY;
944 common_data->ray_depth = 1;
945 DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
947 EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, eprobe->position, prb->clipsta, prb->clipend);
948 EEVEE_lightbake_filter_glossy(
949 sldata, vedata, lbake->rt_color, lbake->store_fb, lbake->cube_offset, prb->intensity,
950 lcache->mips_len, filter_quality, clamp);
952 lcache->cube_len += 1;
954 /* If it's the last probe. */
955 if (lbake->cube_offset == lbake->cube_len - 1) {
956 lcache->flag &= ~LIGHTCACHE_UPDATE_CUBE;
960 static float eevee_lightbake_grid_influence_volume(EEVEE_LightGrid *grid)
962 return mat4_to_scale(grid->mat);
965 static float eevee_lightbake_cube_influence_volume(EEVEE_LightProbe *eprb)
967 return mat4_to_scale(eprb->attenuationmat);
970 static bool eevee_lightbake_grid_comp(EEVEE_LightGrid *grid_a, EEVEE_LightGrid *grid_b)
972 float vol_a = eevee_lightbake_grid_influence_volume(grid_a);
973 float vol_b = eevee_lightbake_grid_influence_volume(grid_b);
974 return (vol_a < vol_b);
977 static bool eevee_lightbake_cube_comp(EEVEE_LightProbe *prb_a, EEVEE_LightProbe *prb_b)
979 float vol_a = eevee_lightbake_cube_influence_volume(prb_a);
980 float vol_b = eevee_lightbake_cube_influence_volume(prb_b);
981 return (vol_a < vol_b);
984 #define SORT_PROBE(elems_type, prbs, elems, elems_len, comp_fn) \
986 bool sorted = false; \
989 for (int i = 0; i < (elems_len) - 1; ++i) { \
990 if ((comp_fn)((elems) + i, (elems) + i+1)) { \
991 SWAP(elems_type, (elems)[i], (elems)[i+1]); \
992 SWAP(LightProbe *, (prbs)[i], (prbs)[i+1]); \
999 static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
1001 Depsgraph *depsgraph = lbake->depsgraph;
1002 Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
1003 LightCache *lcache = scene_eval->eevee.light_cache;
1005 /* At least one for the world */
1008 int total_irr_samples = 1;
1010 /* Convert all lightprobes to tight UBO data from all lightprobes in the scene.
1011 * This allows a large number of probe to be precomputed (even dupli ones). */
1012 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
1014 const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
1015 if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
1019 if (ob->type == OB_LIGHTPROBE) {
1020 LightProbe *prb = (LightProbe *)ob->data;
1022 if (prb->type == LIGHTPROBE_TYPE_GRID) {
1023 lbake->grid_prb[grid_len] = prb;
1024 EEVEE_LightGrid *egrid = &lcache->grid_data[grid_len++];
1025 EEVEE_lightprobes_grid_data_from_object(ob, egrid, &total_irr_samples);
1027 else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
1028 lbake->cube_prb[cube_len] = prb;
1029 EEVEE_LightProbe *eprobe = &lcache->cube_data[cube_len++];
1030 EEVEE_lightprobes_cube_data_from_object(ob, eprobe);
1034 DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
1036 SORT_PROBE(EEVEE_LightGrid, lbake->grid_prb + 1, lcache->grid_data + 1, lbake->grid_len - 1, eevee_lightbake_grid_comp);
1037 SORT_PROBE(EEVEE_LightProbe, lbake->cube_prb + 1, lcache->cube_data + 1, lbake->cube_len - 1, eevee_lightbake_cube_comp);
1039 lbake->total = lbake->total_irr_samples * lbake->bounce_len + lbake->cube_len;
1043 void EEVEE_lightbake_update(void *custom_data)
1045 EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
1046 Scene *scene_orig = lbake->scene;
1048 /* If a new lightcache was created, free the old one and reference the new. */
1049 if (lbake->lcache && scene_orig->eevee.light_cache != lbake->lcache) {
1050 if (scene_orig->eevee.light_cache != NULL) {
1051 EEVEE_lightcache_free(scene_orig->eevee.light_cache);
1053 scene_orig->eevee.light_cache = lbake->lcache;
1054 lbake->own_light_cache = false;
1057 EEVEE_lightcache_info_update(&lbake->scene->eevee);
1059 DEG_id_tag_update(&scene_orig->id, ID_RECALC_COPY_ON_WRITE);
1062 static bool lightbake_do_sample(EEVEE_LightBake *lbake, void (*render_callback)(void *ved, void *user_data))
1064 if (G.is_break == true || *lbake->stop) {
1068 Depsgraph *depsgraph = lbake->depsgraph;
1070 /* TODO: make DRW manager instanciable (and only lock on drawing) */
1071 eevee_lightbake_context_enable(lbake);
1072 DRW_custom_pipeline(&draw_engine_eevee_type, depsgraph, render_callback, lbake);
1074 *lbake->progress = lbake->done / (float)lbake->total;
1075 *lbake->do_update = 1;
1076 eevee_lightbake_context_disable(lbake);
1081 void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float *progress)
1083 EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
1084 Depsgraph *depsgraph = lbake->depsgraph;
1085 int frame = 0; /* TODO make it user param. */
1087 DEG_graph_relations_update(depsgraph, lbake->bmain, lbake->scene, lbake->view_layer_input);
1088 DEG_evaluate_on_framechange(lbake->bmain, depsgraph, frame);
1090 lbake->view_layer = DEG_get_evaluated_view_layer(depsgraph);
1092 lbake->do_update = do_update;
1093 lbake->progress = progress;
1095 /* Count lightprobes */
1096 eevee_lightbake_count_probes(lbake);
1098 /* We need to create the FBOs in the right context.
1099 * We cannot do it in the main thread. */
1100 eevee_lightbake_context_enable(lbake);
1101 eevee_lightbake_create_resources(lbake);
1102 eevee_lightbake_create_render_target(lbake, lbake->rt_res);
1103 eevee_lightbake_context_disable(lbake);
1105 /* Gather all probes data */
1106 eevee_lightbake_gather_probes(lbake);
1108 LightCache *lcache = lbake->lcache;
1110 /* HACK: Sleep to delay the first rendering operation
1111 * that causes a small freeze (caused by VBO generation)
1112 * because this step is locking at this moment. */
1113 /* TODO remove this. */
1115 PIL_sleep_ms(lbake->delay);
1118 /* Render world irradiance and reflection first */
1119 if (lcache->flag & LIGHTCACHE_UPDATE_WORLD) {
1120 lbake->probe = NULL;
1121 lightbake_do_sample(lbake, eevee_lightbake_render_world_sample);
1124 /* Render irradiance grids */
1125 if (lcache->flag & LIGHTCACHE_UPDATE_GRID) {
1126 for (lbake->bounce_curr = 0; lbake->bounce_curr < lbake->bounce_len; ++lbake->bounce_curr) {
1127 /* Bypass world, start at 1. */
1128 lbake->probe = lbake->grid_prb + 1;
1129 lbake->grid = lcache->grid_data + 1;
1130 for (lbake->grid_curr = 1;
1131 lbake->grid_curr < lbake->grid_len;
1132 ++lbake->grid_curr, ++lbake->probe, ++lbake->grid)
1134 LightProbe *prb = *lbake->probe;
1135 lbake->grid_sample_len = prb->grid_resolution_x *
1136 prb->grid_resolution_y *
1137 prb->grid_resolution_z;
1138 for (lbake->grid_sample = 0;
1139 lbake->grid_sample < lbake->grid_sample_len;
1140 ++lbake->grid_sample)
1142 lightbake_do_sample(lbake, eevee_lightbake_render_grid_sample);
1148 /* Render reflections */
1149 if (lcache->flag & LIGHTCACHE_UPDATE_CUBE) {
1150 /* Bypass world, start at 1. */
1151 lbake->probe = lbake->cube_prb + 1;
1152 lbake->cube = lcache->cube_data + 1;
1153 for (lbake->cube_offset = 1;
1154 lbake->cube_offset < lbake->cube_len;
1155 ++lbake->cube_offset, ++lbake->probe, ++lbake->cube)
1157 lightbake_do_sample(lbake, eevee_lightbake_render_probe_sample);
1161 /* Read the resulting lighting data to save it to file/disk. */
1162 eevee_lightbake_context_enable(lbake);
1163 eevee_lightbake_readback_irradiance(lcache);
1164 eevee_lightbake_readback_reflections(lcache);
1165 eevee_lightbake_context_disable(lbake);
1167 lcache->flag |= LIGHTCACHE_BAKED;
1168 lcache->flag &= ~LIGHTCACHE_BAKING;
1170 /* Assume that if lbake->gl_context is NULL
1171 * we are not running in this in a job, so update
1172 * the scene lightcache pointer before deleting it. */
1173 if (lbake->gl_context == NULL) {
1174 BLI_assert(BLI_thread_is_main());
1175 EEVEE_lightbake_update(lbake);
1178 eevee_lightbake_delete_resources(lbake);
1181 /* This is to update the world irradiance and reflection contribution from
1182 * within the viewport drawing (does not have the overhead of a full light cache rebuild.) */
1183 void EEVEE_lightbake_update_world_quick(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, const Scene *scene)
1185 LightCache *lcache = vedata->stl->g_data->light_cache;
1186 float clamp = scene->eevee.gi_glossy_clamp;
1187 float filter_quality = scene->eevee.gi_filter_quality;
1189 EEVEE_LightBake lbake = {
1190 .resource_only = true
1193 /* Create resources. */
1194 eevee_lightbake_create_render_target(&lbake, scene->eevee.gi_cubemap_resolution);
1196 EEVEE_lightbake_cache_init(sldata, vedata, lbake.rt_color, lbake.rt_depth);
1198 sldata->common_data.ray_type = EEVEE_RAY_GLOSSY;
1199 sldata->common_data.ray_depth = 1;
1200 DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
1201 EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
1202 EEVEE_lightbake_filter_glossy(sldata, vedata, lbake.rt_color, lbake.store_fb, 0, 1.0f, lcache->mips_len,
1203 filter_quality, clamp);
1205 sldata->common_data.ray_type = EEVEE_RAY_DIFFUSE;
1206 sldata->common_data.ray_depth = 1;
1207 DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
1208 EEVEE_lightbake_render_world(sldata, vedata, lbake.rt_fb);
1209 EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake.rt_color, lbake.store_fb, 0, 1.0f);
1211 /* Don't hide grids if they are already rendered. */
1212 lcache->grid_len = max_ii(1, lcache->grid_len);
1213 lcache->cube_len = 1;
1215 lcache->flag |= LIGHTCACHE_CUBE_READY | LIGHTCACHE_GRID_READY;
1216 lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
1218 eevee_lightbake_delete_resources(&lbake);