[Bf-blender-cvs] [5d280a2397f] temp-eeveelightcache: Eevee: LightCache: Add back progressive rendering.
Clément Foucault
noreply at git.blender.org
Fri Jun 22 17:46:29 CEST 2018
Commit: 5d280a2397fa349ef72d9410110a6cddbe8f7aaa
Author: Clément Foucault
Date: Thu Jun 21 16:00:21 2018 +0200
Branches: temp-eeveelightcache
https://developer.blender.org/rB5d280a2397fa349ef72d9410110a6cddbe8f7aaa
Eevee: LightCache: Add back progressive rendering.
===================================================================
M source/blender/draw/engines/eevee/eevee_lightcache.c
M source/blender/draw/engines/eevee/eevee_lightprobes.c
M source/blender/editors/render/render_shading.c
===================================================================
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 5a7fe9aa22d..8c5c0f7e804 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -275,12 +275,16 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
lbake->vis_res = eevee->gi_visibility_resolution;
lbake->rt_res = eevee->gi_cubemap_resolution;
+ irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);
+
lbake->ref_cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(lbake->rt_res);
lbake->cube_prb = MEM_callocN(sizeof(LightProbe *) * lbake->cube_count, "EEVEE Cube visgroup ptr");
lbake->grid_prb = MEM_callocN(sizeof(LightProbe *) * lbake->grid_count, "EEVEE Grid visgroup ptr");
- /* Only one render target for now. */
+ lbake->grid_prev = DRW_texture_create_2D_array(lbake->irr_size[0], lbake->irr_size[1], lbake->irr_size[2],
+ IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
+
lbake->rt_depth = DRW_texture_create_cube(lbake->rt_res, GPU_DEPTH_COMPONENT24, 0, NULL);
lbake->rt_color = DRW_texture_create_cube(lbake->rt_res, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL);
@@ -296,11 +300,6 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
GPU_ATTACHMENT_NONE
});
- irradiance_pool_size_get(lbake->vis_res, lbake->total_irr_samples, lbake->irr_size);
-
- lbake->grid_prev = DRW_texture_create_2D_array(lbake->irr_size[0], lbake->irr_size[1], lbake->irr_size[2],
- IRRADIANCE_FORMAT, DRW_TEX_FILTER, NULL);
-
/* Ensure Light Cache is ready to accept new data. If not recreate one.
* WARNING: All the following must be threadsafe. It's currently protected
* by the DRW mutex. */
@@ -321,6 +320,8 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake)
DEG_id_tag_update(&scene_orig->id, DEG_TAG_COPY_ON_WRITE);
}
+ lcache->flag = LIGHTCACHE_UPDATE_WORLD | LIGHTCACHE_UPDATE_CUBE | LIGHTCACHE_UPDATE_GRID;
+
/* Share light cache with the evaluated (baking) layer and the original layer.
* This avoid full scene re-evaluation by depsgraph. */
scene_eval->eevee.light_cache = lcache;
@@ -344,12 +345,11 @@ void *EEVEE_lightbake_job_data_alloc(struct Main *bmain, struct ViewLayer *view_
int frame = 0; /* TODO make it user param. */
DEG_evaluate_on_framechange(lbake->bmain, lbake->depsgraph, frame);
- /* The following needs to run on the main thread. */
-
/* Count lightprobes */
eevee_lightbake_count_probes(lbake);
DRW_opengl_context_enable();
+ /* This function needs to run on the main thread. */
eevee_lightbake_create_resources(lbake);
DRW_opengl_context_disable();
@@ -448,6 +448,17 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
DRW_hair_update();
}
+static void eevee_lightbake_copy_irradiance(EEVEE_LightBake *lbake, EEVEE_LightCache *lcache)
+{
+ DRW_TEXTURE_FREE_SAFE(lbake->grid_prev);
+
+ /* Copy texture by reading back and reuploading it. */
+ float *tex = GPU_texture_read(lcache->grid_tx, 0);
+ lbake->grid_prev = DRW_texture_create_2D_array(lbake->irr_size[0], lbake->irr_size[1], lbake->irr_size[2],
+ IRRADIANCE_FORMAT, DRW_TEX_FILTER, tex);
+ MEM_freeN(tex);
+}
+
static void eevee_lightbake_render_world(void *ved, void *user_data)
{
EEVEE_Data *vedata = (EEVEE_Data *)ved;
@@ -463,12 +474,20 @@ static void eevee_lightbake_render_world(void *ved, void *user_data)
EEVEE_lightbake_filter_glossy(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f);
EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f);
- if (lcache->cube_count == 0) {
- lcache->cube_count = 1;
- }
- if (lcache->grid_count == 0) {
- lcache->grid_count = 1;
- }
+ /* Clear the cache to avoid white values in the grid. */
+ GPU_framebuffer_texture_attach(lbake->store_fb, lbake->grid_prev, 0, 0);
+ GPU_framebuffer_bind(lbake->store_fb);
+ /* Clear to 1.0f for visibility. */
+ GPU_framebuffer_clear_color(lbake->store_fb, (float[4]){1.0f});
+ DRW_draw_pass(vedata->psl->probe_grid_fill);
+
+ SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx);
+
+ /* Make a copy for later. */
+ eevee_lightbake_copy_irradiance(lbake, lcache);
+
+ lcache->cube_count = 1;
+ lcache->grid_count = lbake->grid_count;
lcache->flag |= LIGHTCACHE_CUBE_READY | LIGHTCACHE_GRID_READY;
lcache->flag &= ~LIGHTCACHE_UPDATE_WORLD;
@@ -482,6 +501,47 @@ static void cell_id_to_grid_loc(EEVEE_LightGrid *egrid, int cell_idx, int r_loca
r_local_cell[0] = cell_idx / (egrid->resolution[2] * egrid->resolution[1]);
}
+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)
+{
+ const int cell_count = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z;
+
+ /* Add one for level 0 */
+ int max_lvl = (int)floorf(log2f((float)MAX3(probe->grid_resolution_x,
+ probe->grid_resolution_y,
+ probe->grid_resolution_z)));
+
+ int visited_cells = 0;
+ for (int lvl = max_lvl; lvl >= 0; --lvl) {
+ *r_stride = 1 << lvl;
+ int prev_stride = *r_stride << 1;
+ for (int i = 0; i < cell_count; ++i) {
+ *r_final_idx = i;
+ cell_id_to_grid_loc(egrid, *r_final_idx, r_local_cell);
+ if (((r_local_cell[0] % *r_stride) == 0) &&
+ ((r_local_cell[1] % *r_stride) == 0) &&
+ ((r_local_cell[2] % *r_stride) == 0))
+ {
+ if (!(((r_local_cell[0] % prev_stride) == 0) &&
+ ((r_local_cell[1] % prev_stride) == 0) &&
+ ((r_local_cell[2] % prev_stride) == 0)) ||
+ (i == 0))
+ {
+ if (visited_cells == cell_idx) {
+ return;
+ }
+ else {
+ visited_cells++;
+ }
+ }
+ }
+ }
+ }
+
+ BLI_assert(0);
+}
+
static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, int local_cell[3], float r_pos[3])
{
copy_v3_v3(r_pos, egrid->corner);
@@ -498,30 +558,63 @@ static void eevee_lightbake_render_grid_sample(void *ved, void *user_data)
EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
EEVEE_LightGrid *egrid = lbake->grid;
LightProbe *prb = *lbake->probe;
+ Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph);
+ EEVEE_LightCache *lcache = scene_eval->eevee.light_cache;
+ int grid_loc[3], sample_id, sample_offset, stride;
+ float pos[3];
+ const bool is_last_bounce_sample = ((egrid->offset + lbake->grid_sample) == (lbake->total_irr_samples - 1));
- /* TODO do this once for the whole bake when we have independant DRWManagers. */
+ /* No bias for rendering the probe. */
+ egrid->level_bias = 1.0f;
+
+ /* Use the previous bounce for rendering this bounce. */
+ SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx);
+
+ /* TODO do this once for the whole bake when we have independant DRWManagers.
+ * Warning: Some of the things above require this. */
eevee_lightbake_cache_create(vedata, lbake);
/* Compute sample position */
- int grid_loc[3];
- float pos[3];
- cell_id_to_grid_loc(egrid, lbake->grid_sample, grid_loc);
+ compute_cell_id(egrid, prb, lbake->grid_sample, &sample_id, grid_loc, &stride);
+ sample_offset = egrid->offset + sample_id;
+
grid_loc_to_world_loc(egrid, grid_loc, pos);
/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
common_data->spec_toggle = false;
common_data->prb_num_planar = 0;
common_data->prb_num_render_cube = 0;
- common_data->prb_num_render_grid = 0;
- egrid->level_bias = 1.0f; /* No bias */
+ if (lbake->bounce_curr == 0) {
+ common_data->prb_num_render_grid = 0;
+ }
DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data);
- int sample_offset = egrid->offset + lbake->grid_sample;
EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, pos, prb->clipsta, prb->clipend);
+
+ /* Restore before filtering. */
+ SWAP(GPUTexture *, lbake->grid_prev, lcache->grid_tx);
+
EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, sample_offset, prb->intensity);
- EEVEE_lightbake_filter_visibility(sldata, vedata, lbake->rt_depth, lbake->store_fb, sample_offset,
- prb->clipsta, prb->clipend, egrid->visibility_range,
- prb->vis_blur, lbake->vis_res);
+
+ if (lbake->bounce_curr == 0) {
+ /* We only need to filter the visibility for the first bounce. */
+ EEVEE_lightbake_filter_visibility(sldata, vedata, lbake->rt_depth, lbake->store_fb, sample_offset,
+ prb->clipsta, prb->clipend, egrid->visibility_range,
+ prb->vis_blur, lbake->vis_res);
+ }
+
+ /* Update level for progressive update. */
+ if (lbake->bounce_curr == 0) {
+ egrid->level_bias = (float)(stride << 1);
+ }
+ else if (is_last_bounce_sample) {
+ egrid->level_bias = 1.0f;
+ }
+
+ /* Only run this for the last sample of a bounce. */
+ if (is_last_bounce_sample) {
+ eevee_lightbake_copy_irradiance(lbake, lcache);
+ }
}
static void eevee_lightbake_render_probe(void *ved, void *user_data)
@@ -530,6 +623,7 @@ static void eevee_lightbake_render_probe(void *ved, void *user_data)
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data;
+ EEVEE_LightCache *lcache = lbake->scene->eevee.light_cache;
EEVEE_LightProbe *eprobe = lbake->cube;
LightProbe *prb = *lbake->probe;
@@ -544,6 +638,8 @@ static void eevee_lightbake_render_probe(void *ved, void *user_data)
EEVEE_lightbake_render_scene(sldata, vedata, lbake->rt_fb, eprobe->position, prb->clipsta, prb->clipend);
EEVEE_lightbake_filter_glossy(sldata, vedata, lbake->rt_color, lbake->store_fb, lbake->cube_offset, prb->intensity);
+
+ lcache->cube_count += 1;
}
static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
@@ -597,6 +693,7 @@ static bool lightbake_do_sample(EEVEE_LightBake *lbake, void (*r
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list