From d97a5484afeb7e6d2a2365b5f2c956cbfc86808f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sun, 10 Sep 2017 03:07:55 +0200 Subject: [PATCH] Eevee: Shadows: Update cascaded shadowmaps when rendering probes. This is really resource intensive but there is no other way to correctly handle it. --- .../blender/draw/engines/eevee/eevee_engine.c | 10 ++-- .../draw/engines/eevee/eevee_lightprobes.c | 37 ++++++++------ .../blender/draw/engines/eevee/eevee_lights.c | 17 ++++--- source/blender/draw/intern/draw_manager.c | 50 +++++++++++-------- 4 files changed, 64 insertions(+), 50 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 8d3d749d55a..e8821f23633 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -161,16 +161,16 @@ static void EEVEE_draw_scene(void *vedata) while (loop_ct--) { - /* Refresh shadows */ - DRW_stats_group_start("Shadows"); - EEVEE_draw_shadows(sldata, psl); - DRW_stats_group_end(); - /* Refresh Probes */ DRW_stats_group_start("Probes Refresh"); EEVEE_lightprobes_refresh(sldata, vedata); DRW_stats_group_end(); + /* Refresh shadows */ + DRW_stats_group_start("Shadows"); + EEVEE_draw_shadows(sldata, psl); + DRW_stats_group_end(); + /* Attach depth to the hdr buffer and bind it */ DRW_framebuffer_texture_detach(dtxl->depth); DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index a20b373d3b1..e412d8c79cd 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -996,11 +996,6 @@ static void render_scene_to_probe( float viewmat[4][4], persmat[4][4]; float viewinv[4][4], persinv[4][4]; - DRW_framebuffer_cubeface_attach(sldata->probe_fb, sldata->probe_rt, 0, i, 0); - DRW_framebuffer_viewport_size(sldata->probe_fb, 0, 0, PROBE_RT_SIZE, PROBE_RT_SIZE); - - DRW_framebuffer_clear(false, true, false, NULL, 1.0); - /* Setup custom matrices */ mul_m4_m4m4(viewmat, cubefacemat[i], posmat); mul_m4_m4m4(persmat, winmat, viewmat); @@ -1013,6 +1008,14 @@ static void render_scene_to_probe( DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV); DRW_viewport_matrix_override_set(winmat, DRW_MAT_WIN); + /* Be sure that cascaded shadow maps are updated. */ + EEVEE_draw_shadows(sldata, psl); + + DRW_framebuffer_cubeface_attach(sldata->probe_fb, sldata->probe_rt, 0, i, 0); + DRW_framebuffer_viewport_size(sldata->probe_fb, 0, 0, PROBE_RT_SIZE, PROBE_RT_SIZE); + + DRW_framebuffer_clear(false, true, false, NULL, 1.0); + /* Depth prepass */ DRW_draw_pass(psl->depth_pass); DRW_draw_pass(psl->depth_pass_cull); @@ -1063,6 +1066,20 @@ static void render_scene_to_planar( invert_m4_m4(viewinv, viewmat); invert_m4_m4(persinv, persmat); + DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS); + DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV); + DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW); + DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV); + + /* Since we are rendering with an inverted view matrix, we need + * to invert the facing for backface culling to be the same. */ + DRW_state_invert_facing(); + + /* Be sure that cascaded shadow maps are updated. */ + EEVEE_draw_shadows(sldata, psl); + + DRW_state_clip_planes_add(clip_plane); + /* Attach depth here since it's a DRW_TEX_TEMP */ DRW_framebuffer_texture_layer_attach(fbl->planarref_fb, txl->planar_depth, 0, layer, 0); DRW_framebuffer_texture_layer_attach(fbl->planarref_fb, txl->planar_pool, 0, layer, 0); @@ -1081,16 +1098,6 @@ static void render_scene_to_planar( txl->planar_pool = e_data.planar_pool_placeholder; txl->planar_depth = e_data.depth_array_placeholder; - DRW_viewport_matrix_override_set(persmat, DRW_MAT_PERS); - DRW_viewport_matrix_override_set(persinv, DRW_MAT_PERSINV); - DRW_viewport_matrix_override_set(viewmat, DRW_MAT_VIEW); - DRW_viewport_matrix_override_set(viewinv, DRW_MAT_VIEWINV); - - /* Since we are rendering with an inverted view matrix, we need - * to invert the facing for backface culling to be the same. */ - DRW_state_invert_facing(); - DRW_state_clip_planes_add(clip_plane); - /* Depth prepass */ DRW_draw_pass(psl->depth_pass_clip); DRW_draw_pass(psl->depth_pass_clip_cull); diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index 396318872aa..41537a9f1e3 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -873,14 +873,6 @@ void EEVEE_lights_update(EEVEE_SceneLayerData *sldata) eevee_shadow_cube_setup(ob, linfo, led); delete_pruned_shadowcaster(led); } - - for (i = 0; (ob = linfo->shadow_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) { - EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob); - eevee_shadow_cascade_setup(ob, linfo, led); - } - - DRW_uniformbuffer_update(sldata->light_ubo, &linfo->light_data); - DRW_uniformbuffer_update(sldata->shadow_ubo, &linfo->shadow_data); /* Update all data at once */ } /* this refresh lamps shadow buffers */ @@ -892,6 +884,7 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl) float clear_col[4] = {FLT_MAX}; /* Cube Shadow Maps */ + DRW_stats_group_start("Cube Shadow Maps"); DRW_framebuffer_texture_attach(sldata->shadow_target_fb, sldata->shadow_cube_target, 0, 0); /* Render each shadow to one layer of the array */ for (i = 0; (ob = linfo->shadow_cube_ref[i]) && (i < MAX_SHADOW_CUBE); i++) { @@ -972,8 +965,10 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl) linfo->update_flag &= ~LIGHT_UPDATE_SHADOW_CUBE; DRW_framebuffer_texture_detach(sldata->shadow_cube_target); + DRW_stats_group_end(); /* Cascaded Shadow Maps */ + DRW_stats_group_start("Cascaded Shadow Maps"); DRW_framebuffer_texture_attach(sldata->shadow_target_fb, sldata->shadow_cascade_target, 0, 0); for (i = 0; (ob = linfo->shadow_cascade_ref[i]) && (i < MAX_SHADOW_CASCADE); i++) { EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob); @@ -982,6 +977,8 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl) EEVEE_ShadowCascadeData *evscd = (EEVEE_ShadowCascadeData *)led->storage; EEVEE_ShadowRender *srd = &linfo->shadow_render_data; + eevee_shadow_cascade_setup(ob, linfo, led); + srd->clip_near = la->clipsta; srd->clip_far = la->clipend; for (int j = 0; j < la->cascade_count; ++j) { @@ -1040,6 +1037,10 @@ void EEVEE_draw_shadows(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl) } DRW_framebuffer_texture_detach(sldata->shadow_cascade_target); + DRW_stats_group_end(); + + DRW_uniformbuffer_update(sldata->light_ubo, &linfo->light_data); + DRW_uniformbuffer_update(sldata->shadow_ubo, &linfo->shadow_data); /* Update all data at once */ } void EEVEE_lights_free(void) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 7d2c7819ba3..bc9cb46168e 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2526,29 +2526,35 @@ static void DRW_viewport_var_init(void) void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type) { RegionView3D *rv3d = DST.draw_ctx.rv3d; + BLI_assert(type >= DRW_MAT_PERS && type <= DRW_MAT_WININV); - switch (type) { - case DRW_MAT_PERS: - copy_m4_m4(mat, rv3d->persmat); - break; - case DRW_MAT_PERSINV: - copy_m4_m4(mat, rv3d->persinv); - break; - case DRW_MAT_VIEW: - copy_m4_m4(mat, rv3d->viewmat); - break; - case DRW_MAT_VIEWINV: - copy_m4_m4(mat, rv3d->viewinv); - break; - case DRW_MAT_WIN: - copy_m4_m4(mat, rv3d->winmat); - break; - case DRW_MAT_WININV: - invert_m4_m4(mat, rv3d->winmat); - break; - default: - BLI_assert(!"Matrix type invalid"); - break; + if (viewport_matrix_override.override[type]) { + copy_m4_m4(mat, viewport_matrix_override.mat[type]); + } + else { + switch (type) { + case DRW_MAT_PERS: + copy_m4_m4(mat, rv3d->persmat); + break; + case DRW_MAT_PERSINV: + copy_m4_m4(mat, rv3d->persinv); + break; + case DRW_MAT_VIEW: + copy_m4_m4(mat, rv3d->viewmat); + break; + case DRW_MAT_VIEWINV: + copy_m4_m4(mat, rv3d->viewinv); + break; + case DRW_MAT_WIN: + copy_m4_m4(mat, rv3d->winmat); + break; + case DRW_MAT_WININV: + invert_m4_m4(mat, rv3d->winmat); + break; + default: + BLI_assert(!"Matrix type invalid"); + break; + } } }