From f7d415ab42c3203d370b62d6ed99e7a894030a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 14 Mar 2019 16:51:34 +0100 Subject: Fix T58610: EEVEE: camera motion blur renders only one viewport sample This fix saves the camera matrices in order to not call BKE_animsys_evaluate_animdata during each draw loop. This function tags the view as dirty even if the camera does not move. This effectivly, avoids the constant reset of TAA. --- .../blender/draw/engines/eevee/eevee_motion_blur.c | 77 ++++++++++++++-------- source/blender/draw/engines/eevee/eevee_private.h | 2 + .../draw/engines/eevee/eevee_temporal_sampling.c | 5 +- 3 files changed, 54 insertions(+), 30 deletions(-) (limited to 'source/blender') diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index 9ffd2006998..70db2adedbf 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -32,6 +32,7 @@ #include "DNA_camera_types.h" #include "DNA_screen_types.h" +#include "ED_screen.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -56,9 +57,8 @@ static void eevee_motion_blur_camera_get_matrix_at_time( float obmat[4][4]; /* HACK */ - Object cam_cpy; Camera camdata_cpy; - memcpy(&cam_cpy, camera, sizeof(cam_cpy)); - memcpy(&camdata_cpy, camera->data, sizeof(camdata_cpy)); + Object cam_cpy = *camera; + Camera camdata_cpy = *(Camera *)(camera->data); cam_cpy.data = &camdata_cpy; const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -116,40 +116,65 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda float delta = scene_eval->eevee.motion_blur_shutter; Object *ob_camera_eval = DEG_get_evaluated_object(draw_ctx->depsgraph, camera); - /* Current matrix */ - eevee_motion_blur_camera_get_matrix_at_time( - scene, - ar, rv3d, v3d, - ob_camera_eval, - ctime, - effects->current_ndc_to_world); - /* Viewport Matrix */ + /* Note: This does not have TAA jitter applied. */ DRW_viewport_matrix_get(persmat, DRW_MAT_PERS); - /* Only continue if camera is not being keyed */ - if (DRW_state_is_image_render() || - compare_m4m4(persmat, effects->current_ndc_to_world, 0.0001f)) - { - /* Past matrix */ + bool view_is_valid = (stl->g_data->view_updated == false); + + if (draw_ctx->evil_C != NULL) { + struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C); + view_is_valid = view_is_valid && (ED_screen_animation_no_scrub(wm) == NULL); + } + + /* The view is jittered by the oglrenderer. So avoid testing in this case. */ + if (!DRW_state_is_image_render()) { + view_is_valid = view_is_valid && compare_m4m4(persmat, effects->prev_drw_persmat, FLT_MIN); + /* WATCH: assume TAA init code runs last. */ + if (scene_eval->eevee.taa_samples == 1) { + /* Only if TAA is disabled. If not, TAA will update prev_drw_persmat itself. */ + copy_m4_m4(effects->prev_drw_persmat, persmat); + } + } + + effects->motion_blur_mat_cached = view_is_valid && !DRW_state_is_image_render(); + + /* Current matrix */ + if (effects->motion_blur_mat_cached == false) { eevee_motion_blur_camera_get_matrix_at_time( scene, ar, rv3d, v3d, ob_camera_eval, - ctime - delta, - effects->past_world_to_ndc); + ctime, + effects->current_world_to_ndc); + } + + /* Only continue if camera is not being keyed */ + if (DRW_state_is_image_render() || + compare_m4m4(persmat, effects->current_world_to_ndc, 0.0001f)) + { + /* Past matrix */ + if (effects->motion_blur_mat_cached == false) { + eevee_motion_blur_camera_get_matrix_at_time( + scene, + ar, rv3d, v3d, + ob_camera_eval, + ctime - delta, + effects->past_world_to_ndc); #if 0 /* for future high quality blur */ - /* Future matrix */ - eevee_motion_blur_camera_get_matrix_at_time( - scene, - ar, rv3d, v3d, - ob_camera_eval, - ctime + delta, - effects->future_world_to_ndc); + /* Future matrix */ + eevee_motion_blur_camera_get_matrix_at_time( + scene, + ar, rv3d, v3d, + ob_camera_eval, + ctime + delta, + effects->future_world_to_ndc); #endif - invert_m4(effects->current_ndc_to_world); + invert_m4_m4(effects->current_ndc_to_world, effects->current_world_to_ndc); + } + effects->motion_blur_mat_cached = true; effects->motion_blur_samples = scene_eval->eevee.motion_blur_samples; if (!e_data.motion_blur_sh) { diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 8656db8e075..7ffe7f46811 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -563,9 +563,11 @@ typedef struct EEVEE_EffectsInfo { struct GPUTexture *gtao_horizons; /* Textures from pool */ struct GPUTexture *gtao_horizons_debug; /* Motion Blur */ + float current_world_to_ndc[4][4]; float current_ndc_to_world[4][4]; float past_world_to_ndc[4][4]; int motion_blur_samples; + bool motion_blur_mat_cached; /* Velocity Pass */ float velocity_curr_persinv[4][4]; float velocity_past_persmat[4][4]; diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 67ac6126148..592d11916ac 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -179,10 +179,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data const DRWContextState *draw_ctx = DRW_context_state_get(); const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if (((scene_eval->eevee.taa_samples != 1) && - /* FIXME the motion blur camera evaluation is tagging view_updated - * thus making the TAA always reset and never stopping rendering. */ - (effects->enabled_effects & EFFECT_MOTION_BLUR) == 0) || + if ((scene_eval->eevee.taa_samples != 1) || DRW_state_is_image_render()) { float persmat[4][4], viewmat[4][4]; -- cgit v1.2.3