Fix T58610: EEVEE: camera motion blur renders only one viewport sample
authorClément Foucault <foucault.clem@gmail.com>
Thu, 14 Mar 2019 15:51:34 +0000 (16:51 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Thu, 14 Mar 2019 15:53:05 +0000 (16:53 +0100)
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.

source/blender/draw/engines/eevee/eevee_motion_blur.c
source/blender/draw/engines/eevee/eevee_private.h
source/blender/draw/engines/eevee/eevee_temporal_sampling.c

index 9ffd20069983b39d75cb10cfa84007f90c20a310..70db2adedbfbb65d15253667334c2accc3dd88d1 100644 (file)
@@ -32,6 +32,7 @@
 #include "DNA_camera_types.h"
 #include "DNA_screen_types.h"
 
 #include "DNA_camera_types.h"
 #include "DNA_screen_types.h"
 
+#include "ED_screen.h"
 
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.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 */
        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();
        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);
 
                        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 */
                        /* Viewport Matrix */
+                       /* Note: This does not have TAA jitter applied. */
                        DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
 
                        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,
                                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 */
 
 #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
 #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) {
                                effects->motion_blur_samples = scene_eval->eevee.motion_blur_samples;
 
                                if (!e_data.motion_blur_sh) {
index 8656db8e0756d501c99de5d33ec9a22ca9f8a6a0..7ffe7f468110c412ec76dc48548fa763ecf983c5 100644 (file)
@@ -563,9 +563,11 @@ typedef struct EEVEE_EffectsInfo {
        struct GPUTexture *gtao_horizons; /* Textures from pool */
        struct GPUTexture *gtao_horizons_debug;
        /* Motion Blur */
        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;
        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];
        /* Velocity Pass */
        float velocity_curr_persinv[4][4];
        float velocity_past_persmat[4][4];
index 67ac61261489d2727fdd5d97b609bc56af4c5ed1..592d11916acd01550be9122dc7c6e696f426dc8c 100644 (file)
@@ -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);
 
        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];
            DRW_state_is_image_render())
        {
                float persmat[4][4], viewmat[4][4];