EEVEE: Viewport Rendering TAA
authorJeroen Bakker <j.bakker@atmind.nl>
Thu, 16 May 2019 09:40:07 +0000 (11:40 +0200)
committerJeroen Bakker <j.bakker@atmind.nl>
Thu, 16 May 2019 14:02:56 +0000 (16:02 +0200)
EEVEE assumed that the OGL renderer did FSAA, as the FSAA was removed we
needed to revalidate this assumption. The temporal sampling only inited
the matrices during init phase. As now we need to update the matrices
for every sample rendered the code for updating the matrices was
isolated in a new function `EEVEE_temporal_sampling_update_matrices`.

Reviewed By: fclem

Maniphest Tasks: T64646

Differential Revision: https://developer.blender.org/D4871

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

index 26f33f4..68dc9ef 100644 (file)
@@ -219,6 +219,14 @@ static void eevee_draw_background(void *vedata)
       DRW_viewport_matrix_override_set(stl->effects->overide_wininv, DRW_MAT_WININV);
     }
 
+    /* when doing viewport rendering the overrides needs to be recalculated for
+     * every loop as this normally happens once inside
+     * `EEVEE_temporal_sampling_init` */
+    else if (((stl->effects->enabled_effects & EFFECT_TAA) != 0) &&
+             (stl->effects->taa_current_sample > 1) && DRW_state_is_image_render()) {
+      EEVEE_temporal_sampling_update_matrices(vedata);
+    }
+
     /* Refresh Probes */
     DRW_stats_group_start("Probes Refresh");
     EEVEE_lightprobes_refresh(sldata, vedata);
@@ -297,7 +305,7 @@ static void eevee_draw_background(void *vedata)
     EEVEE_draw_effects(sldata, vedata);
     DRW_stats_group_end();
 
-    if ((stl->effects->taa_current_sample > 1) && !DRW_state_is_image_render()) {
+    if ((stl->effects->taa_current_sample > 1)) {
       DRW_viewport_matrix_override_unset_all();
     }
   }
index ca9314d..f9ba3bb 100644 (file)
@@ -1058,6 +1058,7 @@ void EEVEE_temporal_sampling_matrices_calc(EEVEE_EffectsInfo *effects,
                                            float viewmat[4][4],
                                            float persmat[4][4],
                                            const double ht_point[2]);
+void EEVEE_temporal_sampling_update_matrices(EEVEE_Data *vedata);
 void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
 void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata);
 
index 1b7adba..b191962 100644 (file)
@@ -160,6 +160,32 @@ void EEVEE_temporal_sampling_matrices_calc(EEVEE_EffectsInfo *effects,
   invert_m4_m4(effects->overide_wininv, effects->overide_winmat);
 }
 
+/* Update the matrices based on the current sample.
+ * Note: `DRW_MAT_PERS` and `DRW_MAT_VIEW` needs to read the original matrices. */
+void EEVEE_temporal_sampling_update_matrices(EEVEE_Data *vedata)
+{
+  EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+  EEVEE_EffectsInfo *effects = stl->effects;
+
+  float persmat[4][4], viewmat[4][4];
+  double ht_point[2];
+  double ht_offset[2] = {0.0, 0.0};
+  uint ht_primes[2] = {2, 3};
+
+  DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
+  DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
+  DRW_viewport_matrix_get(effects->overide_winmat, DRW_MAT_WIN);
+
+  BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample - 1, ht_point);
+
+  EEVEE_temporal_sampling_matrices_calc(effects, viewmat, persmat, ht_point);
+
+  DRW_viewport_matrix_override_set(effects->overide_persmat, DRW_MAT_PERS);
+  DRW_viewport_matrix_override_set(effects->overide_persinv, DRW_MAT_PERSINV);
+  DRW_viewport_matrix_override_set(effects->overide_winmat, DRW_MAT_WIN);
+  DRW_viewport_matrix_override_set(effects->overide_wininv, DRW_MAT_WININV);
+}
+
 void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata)
 {
   vedata->stl->effects->taa_render_sample = 1;
@@ -212,12 +238,8 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
 
     DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
     DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
-    DRW_viewport_matrix_get(effects->overide_winmat, DRW_MAT_WIN);
-    /* 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);
-      copy_m4_m4(effects->prev_drw_persmat, persmat);
-    }
+    view_is_valid = view_is_valid && compare_m4m4(persmat, effects->prev_drw_persmat, FLT_MIN);
+    copy_m4_m4(effects->prev_drw_persmat, persmat);
 
     /* Prevent ghosting from probe data. */
     view_is_valid = view_is_valid && (effects->prev_drw_support == DRW_state_draw_support());
@@ -227,23 +249,11 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
          (effects->taa_current_sample < effects->taa_total_sample)) ||
         DRW_state_is_image_render()) {
       if (view_is_valid) {
-        /* OGL render already jitter the camera. */
+        /* Viewport rendering updates the matrices in `eevee_draw_background` */
         if (!DRW_state_is_image_render()) {
           effects->taa_current_sample += 1;
           repro_flag = 0;
-
-          double ht_point[2];
-          double ht_offset[2] = {0.0, 0.0};
-          uint ht_primes[2] = {2, 3};
-
-          BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample - 1, ht_point);
-
-          EEVEE_temporal_sampling_matrices_calc(effects, viewmat, persmat, ht_point);
-
-          DRW_viewport_matrix_override_set(effects->overide_persmat, DRW_MAT_PERS);
-          DRW_viewport_matrix_override_set(effects->overide_persinv, DRW_MAT_PERSINV);
-          DRW_viewport_matrix_override_set(effects->overide_winmat, DRW_MAT_WIN);
-          DRW_viewport_matrix_override_set(effects->overide_wininv, DRW_MAT_WININV);
+          EEVEE_temporal_sampling_update_matrices(vedata);
         }
       }
       else {
@@ -313,19 +323,15 @@ void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata)
       DRW_draw_pass(psl->taa_resolve);
 
       /* Restore the depth from sample 1. */
-      if (!DRW_state_is_image_render()) {
-        GPU_framebuffer_blit(fbl->double_buffer_depth_fb, 0, fbl->main_fb, 0, GPU_DEPTH_BIT);
-      }
+      GPU_framebuffer_blit(fbl->double_buffer_depth_fb, 0, fbl->main_fb, 0, GPU_DEPTH_BIT);
 
       SWAP_BUFFERS_TAA();
     }
     else {
-      if (!DRW_state_is_image_render()) {
-        /* Save the depth buffer for the next frame.
-         * This saves us from doing anything special
-         * in the other mode engines. */
-        GPU_framebuffer_blit(fbl->main_fb, 0, fbl->double_buffer_depth_fb, 0, GPU_DEPTH_BIT);
-      }
+      /* Save the depth buffer for the next frame.
+       * This saves us from doing anything special
+       * in the other mode engines. */
+      GPU_framebuffer_blit(fbl->main_fb, 0, fbl->double_buffer_depth_fb, 0, GPU_DEPTH_BIT);
 
       /* Do reprojection for noise reduction */
       /* TODO : do AA jitter if in only render view. */