Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2018-06-25 10:06:39 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2018-06-26 17:35:47 +0300
commitcf8a0597693de8fbf3dccf607d81e6e1f2c0d2aa (patch)
treeeea2c1b0fbe0313d196e41ace1cd42b9ade50469 /source/blender/draw
parentc07f2bc89196ea449a2875634eb85efa45733fb5 (diff)
Workbench: Tempural Anti Aliasing
- FXAA is now also done in the workbench_forward engine. - User can enable TAA8 in the userpref by setting their max viewport AA to TAA8. FXAA will still be used when navigating
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt3
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl15
-rw-r--r--source/blender/draw/engines/workbench/solid_mode.c8
-rw-r--r--source/blender/draw/engines/workbench/workbench_data.c6
-rw-r--r--source/blender/draw/engines/workbench/workbench_deferred.c75
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_fxaa.c80
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_taa.c207
-rw-r--r--source/blender/draw/engines/workbench/workbench_forward.c26
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h54
9 files changed, 433 insertions, 41 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 2f268663186..a68ccc0da93 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -111,6 +111,8 @@ set(SRC
engines/workbench/workbench_data.c
engines/workbench/workbench_engine.c
engines/workbench/workbench_deferred.c
+ engines/workbench/workbench_effect_fxaa.c
+ engines/workbench/workbench_effect_taa.c
engines/workbench/workbench_forward.c
engines/workbench/workbench_materials.c
engines/workbench/workbench_studiolight.c
@@ -209,6 +211,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_common_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_data_lib.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_deferred_composite_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_effect_fxaa_frag.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_effect_taa_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_forward_composite_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_forward_depth_frag.glsl SRC)
data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl SRC)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl
new file mode 100644
index 00000000000..d962ffedf1f
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_taa_frag.glsl
@@ -0,0 +1,15 @@
+uniform sampler2D historyBuffer;
+uniform sampler2D colorBuffer;
+
+out vec4 colorOutput;
+
+uniform float mixFactor;
+
+void main()
+{
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+
+ vec4 history_buffer = texelFetch(historyBuffer, texel, 0);
+ vec4 color_buffer = texelFetch(colorBuffer, texel, 0);
+ colorOutput = mix(history_buffer, color_buffer, mixFactor);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/workbench/solid_mode.c b/source/blender/draw/engines/workbench/solid_mode.c
index 1e49d1ae573..a3a42e10c8e 100644
--- a/source/blender/draw/engines/workbench/solid_mode.c
+++ b/source/blender/draw/engines/workbench/solid_mode.c
@@ -76,6 +76,12 @@ static void workbench_solid_engine_free(void)
workbench_deferred_engine_free();
}
+static void workbench_solid_view_update(void *vedata)
+{
+ WORKBENCH_Data *data = vedata;
+ workbench_taa_view_updated(data);
+}
+
static const DrawEngineDataSize workbench_data_size = DRW_VIEWPORT_DATA_SIZE(WORKBENCH_Data);
DrawEngineType draw_engine_workbench_solid = {
@@ -89,7 +95,7 @@ DrawEngineType draw_engine_workbench_solid = {
&workbench_solid_cache_finish,
&workbench_solid_draw_background,
&workbench_solid_draw_scene,
- NULL,
+ &workbench_solid_view_update,
NULL,
NULL,
};
diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c
index d544e7614ab..a72f3a673b5 100644
--- a/source/blender/draw/engines/workbench/workbench_data.c
+++ b/source/blender/draw/engines/workbench/workbench_data.c
@@ -5,6 +5,12 @@
#include "UI_resources.h"
+void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info)
+{
+ effect_info->jitter_index = 0;
+ effect_info->view_updated = true;
+}
+
void workbench_private_data_init(WORKBENCH_PrivateData *wpd)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c
index 4fe3e92f10c..96ed345ed45 100644
--- a/source/blender/draw/engines/workbench/workbench_deferred.c
+++ b/source/blender/draw/engines/workbench/workbench_deferred.c
@@ -65,7 +65,6 @@ static struct {
struct GPUShader *shadow_pass_manifold_sh;
struct GPUShader *shadow_caps_sh;
struct GPUShader *shadow_caps_manifold_sh;
- struct GPUShader *effect_fxaa_sh;
struct GPUTexture *object_id_tx; /* ref only, not alloced */
struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
@@ -85,8 +84,6 @@ static struct {
} e_data = {{NULL}};
/* Shaders */
-extern char datatoc_common_fxaa_lib_glsl[];
-extern char datatoc_common_fullscreen_vert_glsl[];
extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_workbench_prepass_vert_glsl[];
@@ -103,7 +100,6 @@ extern char datatoc_workbench_background_lib_glsl[];
extern char datatoc_workbench_cavity_lib_glsl[];
extern char datatoc_workbench_common_lib_glsl[];
extern char datatoc_workbench_data_lib_glsl[];
-extern char datatoc_workbench_effect_fxaa_frag_glsl[];
extern char datatoc_workbench_object_outline_lib_glsl[];
extern char datatoc_workbench_world_light_lib_glsl[];
@@ -219,7 +215,7 @@ static void select_deferred_shaders(WORKBENCH_PrivateData *wpd)
static float *create_disk_samples(int num_samples)
{
/* vec4 to ensure memory alignment. */
- float (*texels)[4] = MEM_mallocN(sizeof(float[4]) * num_samples, "concentric_tex");
+ float (*texels)[4] = MEM_mallocN(sizeof(float[4]) * num_samples, __func__);
const float num_samples_inv = 1.0f / num_samples;
for (int i = 0; i < num_samples; i++) {
@@ -272,9 +268,19 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
{
WORKBENCH_FramebufferList *fbl = vedata->fbl;
WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_TextureList *txl = vedata->txl;
WORKBENCH_PassList *psl = vedata->psl;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ if (!stl->g_data) {
+ /* Alloc transient pointers */
+ stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
+ }
+ if (!stl->effects) {
+ stl->effects = MEM_mallocN(sizeof(*stl->effects), __func__);
+ workbench_effect_info_init(stl->effects);
+ }
+
if (!e_data.next_object_id) {
memset(e_data.prepass_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
memset(e_data.composite_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
@@ -322,17 +328,10 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
e_data.cavity_sh = DRW_shader_create_fullscreen(cavity_frag, NULL);
MEM_freeN(cavity_frag);
- e_data.effect_fxaa_sh = DRW_shader_create_with_lib(
- datatoc_common_fullscreen_vert_glsl, NULL,
- datatoc_workbench_effect_fxaa_frag_glsl,
- datatoc_common_fxaa_lib_glsl,
- NULL);
}
+ workbench_fxaa_engine_init();
+ workbench_taa_engine_init(vedata);
- if (!stl->g_data) {
- /* Alloc transient pointers */
- stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
- }
WORKBENCH_PrivateData *wpd = stl->g_data;
workbench_private_data_init(wpd);
@@ -424,15 +423,20 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
}
{
- psl->effect_fxaa_pass = DRW_pass_create("Effect FXAA", DRW_STATE_WRITE_COLOR);
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_fxaa_sh, psl->effect_fxaa_pass);
- DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.effect_buffer_tx);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ if (TAA_ENABLED(wpd)) {
+ psl->effect_aa_pass = workbench_taa_create_pass(txl, stl->effects, fbl, &e_data.composite_buffer_tx);
+ }
+ else if (FXAA_ENABLED(wpd)) {
+ psl->effect_aa_pass = workbench_fxaa_create_pass(&e_data.effect_buffer_tx);
+ stl->effects->jitter_index = 0;
+ }
+ else {
+ psl->effect_aa_pass = NULL;
+ }
}
}
-void workbench_deferred_engine_free()
+void workbench_deferred_engine_free(void)
{
for (int index = 0; index < MAX_SHADERS; index++) {
DRW_SHADER_FREE_SAFE(e_data.prepass_sh_cache[index]);
@@ -449,7 +453,8 @@ void workbench_deferred_engine_free()
DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
DRW_SHADER_FREE_SAFE(e_data.shadow_caps_manifold_sh);
- DRW_SHADER_FREE_SAFE(e_data.effect_fxaa_sh);
+ workbench_fxaa_engine_free();
+ workbench_taa_engine_free();
}
static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
@@ -834,7 +839,14 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_FramebufferList *fbl = vedata->fbl;
WORKBENCH_PrivateData *wpd = stl->g_data;
+ WORKBENCH_EffectInfo *effect_info = stl->effects;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ const bool taa_enabled = TAA_ENABLED(wpd);
+
+ if (taa_enabled)
+ {
+ workbench_taa_draw_scene_start(effect_info);
+ }
/* clear in background */
GPU_framebuffer_bind(fbl->prepass_fb);
@@ -870,21 +882,14 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
DRW_draw_pass(psl->composite_pass);
}
- if (FXAA_ENABLED(wpd)) {
- GPU_framebuffer_bind(fbl->effect_fb);
- DRW_transform_to_display(e_data.composite_buffer_tx);
-
- /* TODO: when rendering the fxaa pass should be done in display space
- Currently we do not support rendering in the workbench
- */
- GPU_framebuffer_bind(dfbl->color_only_fb);
- DRW_draw_pass(psl->effect_fxaa_pass);
- }
- else {
- GPU_framebuffer_bind(dfbl->color_only_fb);
- DRW_transform_to_display(e_data.composite_buffer_tx);
+ GPUTexture *final_color_tx = e_data.composite_buffer_tx;
+ if (taa_enabled)
+ {
+ workbench_taa_draw_pass(effect_info, psl->effect_aa_pass);
+ final_color_tx = effect_info->final_color_tx;
+ workbench_taa_draw_scene_end(vedata);
}
-
+ workbench_fxaa_draw_pass(wpd, fbl->effect_fb, final_color_tx, psl->effect_aa_pass);
workbench_private_data_free(wpd);
}
diff --git a/source/blender/draw/engines/workbench/workbench_effect_fxaa.c b/source/blender/draw/engines/workbench/workbench_effect_fxaa.c
new file mode 100644
index 00000000000..2746a4f14f8
--- /dev/null
+++ b/source/blender/draw/engines/workbench/workbench_effect_fxaa.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file workbench_effect_fxaa.c
+ * \ingroup draw_engine
+ */
+#include "workbench_private.h"
+
+/* *********** STATIC *********** */
+static struct {
+ struct GPUShader *effect_fxaa_sh;
+} e_data = {NULL};
+
+/* Shaders */
+extern char datatoc_common_fxaa_lib_glsl[];
+extern char datatoc_common_fullscreen_vert_glsl[];
+extern char datatoc_workbench_effect_fxaa_frag_glsl[];
+
+/* *********** Functions *********** */
+void workbench_fxaa_engine_init(void)
+{
+ if (e_data.effect_fxaa_sh == NULL)
+ {
+ e_data.effect_fxaa_sh = DRW_shader_create_with_lib(
+ datatoc_common_fullscreen_vert_glsl, NULL,
+ datatoc_workbench_effect_fxaa_frag_glsl,
+ datatoc_common_fxaa_lib_glsl,
+ NULL);
+ }
+}
+
+DRWPass *workbench_fxaa_create_pass(GPUTexture **color_buffer_tx)
+{
+ DRWPass *pass = DRW_pass_create("Effect FXAA", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_fxaa_sh, pass);
+ DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", color_buffer_tx);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ return pass;
+}
+
+void workbench_fxaa_draw_pass(WORKBENCH_PrivateData *wpd, GPUFrameBuffer *fb, GPUTexture *tx, DRWPass *effect_aa_pass)
+{
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ if (FXAA_ENABLED(wpd)) {
+ GPU_framebuffer_bind(fb);
+ DRW_transform_to_display(tx);
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_draw_pass(effect_aa_pass);
+ }
+ else {
+ GPU_framebuffer_bind(dfbl->color_only_fb);
+ DRW_transform_to_display(tx);
+ }
+
+}
+
+void workbench_fxaa_engine_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.effect_fxaa_sh);
+}
+
diff --git a/source/blender/draw/engines/workbench/workbench_effect_taa.c b/source/blender/draw/engines/workbench/workbench_effect_taa.c
new file mode 100644
index 00000000000..deebac05096
--- /dev/null
+++ b/source/blender/draw/engines/workbench/workbench_effect_taa.c
@@ -0,0 +1,207 @@
+
+#include "workbench_private.h"
+
+static struct {
+ struct GPUShader *effect_taa_sh;
+
+} e_data = {NULL};
+
+extern char datatoc_workbench_effect_taa_frag_glsl[];
+
+/*
+ * Sub-sample positions for TAA8
+ * first sample needs to be at 0.0f, 0.0f
+ * as that sample depicts the z-buffer
+ */
+static const float SAMPLE_LOCS_8[8][2] = {
+ { 0.125f-0.125f, 0.375f-0.375f},
+ {-0.625f-0.125f, -0.625f-0.375f},
+ { 0.875f-0.125f, 0.875f-0.375f},
+ {-0.875f-0.125f, 0.125f-0.375f},
+ { 0.625f-0.125f, -0.125f-0.375f},
+ {-0.375f-0.125f, 0.625f-0.375f},
+ { 0.375f-0.125f, -0.875f-0.375f},
+ {-0.125f-0.125f, -0.375f-0.375f},
+};
+
+void workbench_taa_engine_init(WORKBENCH_Data *vedata)
+{
+ WORKBENCH_EffectInfo *effect_info = vedata->stl->effects;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ RegionView3D *rv3d = draw_ctx->rv3d;
+
+ if (e_data.effect_taa_sh == NULL)
+ {
+ e_data.effect_taa_sh = DRW_shader_create_fullscreen(datatoc_workbench_effect_taa_frag_glsl, NULL);
+ }
+
+ /* reset complete drawing when navigating. */
+ if (effect_info->jitter_index != 0)
+ {
+ if (rv3d && rv3d->rflag & RV3D_NAVIGATING)
+ {
+ effect_info->jitter_index = 0;
+ }
+ }
+
+ if (effect_info->view_updated)
+ {
+ effect_info->jitter_index = 0;
+ effect_info->view_updated = false;
+ }
+
+ {
+ float view[4][4];
+ float win[4][4];
+ DRW_viewport_matrix_get(view, DRW_MAT_VIEW);
+ DRW_viewport_matrix_get(win, DRW_MAT_WIN);
+ mul_m4_m4m4(effect_info->curr_mat, view, win);
+ if(!equals_m4m4(effect_info->curr_mat, effect_info->last_mat)){
+ effect_info->jitter_index = 0;
+ }
+ }
+}
+
+void workbench_taa_engine_free(void)
+{
+ DRW_SHADER_FREE_SAFE(e_data.effect_taa_sh);
+}
+
+
+DRWPass *workbench_taa_create_pass(WORKBENCH_TextureList *txl, WORKBENCH_EffectInfo *effect_info, WORKBENCH_FramebufferList *fbl, GPUTexture **color_buffer_tx)
+{
+ /*
+ * jitter_index is not updated yet. This will be done in during draw phase.
+ * so for now it is inversed.
+ */
+ int previous_jitter_index = effect_info->jitter_index;
+ bool previous_jitter_even = (previous_jitter_index & 1) == 0;
+
+ {
+ DRW_texture_ensure_fullscreen_2D(&txl->history_buffer1_tx, GPU_RGBA16F, 0);
+ DRW_texture_ensure_fullscreen_2D(&txl->history_buffer2_tx, GPU_RGBA16F, 0);
+ DRW_texture_ensure_fullscreen_2D(&txl->depth_buffer_tx, GPU_DEPTH24_STENCIL8, 0);
+ }
+
+ {
+ GPU_framebuffer_ensure_config(&fbl->effect_taa_even_fb, {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->history_buffer1_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->effect_taa_uneven_fb, {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->history_buffer2_tx),
+ });
+ GPU_framebuffer_ensure_config(&fbl->depth_buffer_fb, {
+ GPU_ATTACHMENT_TEXTURE(txl->depth_buffer_tx),
+ });
+ }
+
+
+ DRWPass *pass = DRW_pass_create("Effect TAA", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_taa_sh, pass);
+ DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", color_buffer_tx);
+ if (previous_jitter_even) {
+ DRW_shgroup_uniform_texture_ref(grp, "historyBuffer", &txl->history_buffer2_tx);
+ }
+ else {
+ DRW_shgroup_uniform_texture_ref(grp, "historyBuffer", &txl->history_buffer1_tx);
+ }
+
+ DRW_shgroup_uniform_float(grp, "mixFactor", &effect_info->taa_mix_factor, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+
+ if (previous_jitter_even)
+ {
+ effect_info->final_color_tx = txl->history_buffer1_tx;
+ effect_info->final_color_fb = fbl->effect_taa_even_fb;
+ }
+ else {
+ effect_info->final_color_tx = txl->history_buffer2_tx;
+ effect_info->final_color_fb = fbl->effect_taa_uneven_fb;
+ }
+ return pass;
+}
+
+void workbench_taa_draw_scene_start(WORKBENCH_EffectInfo *effect_info)
+{
+ const float *viewport_size = DRW_viewport_size_get();
+ const int samples = 8;
+ float mix_factor;
+
+ mix_factor = 1.0f / (effect_info->jitter_index + 1);
+
+ const int bitmask = samples - 1;
+ const int jitter_index = effect_info->jitter_index;
+ const float *transform_offset = SAMPLE_LOCS_8[jitter_index];
+ effect_info->jitter_index = (jitter_index + 1) & bitmask;
+
+ /* construct new matrices from transform delta */
+ float viewmat[4][4];
+ float persmat[4][4];
+ DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
+ DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
+ DRW_viewport_matrix_get(effect_info->override_winmat, DRW_MAT_WIN);
+
+ window_translate_m4(
+ effect_info->override_winmat, persmat,
+ transform_offset[0] / viewport_size[0],
+ transform_offset[1] / viewport_size[1]);
+
+ mul_m4_m4m4(effect_info->override_persmat, effect_info->override_winmat, viewmat);
+ invert_m4_m4(effect_info->override_persinv, effect_info->override_persmat);
+ invert_m4_m4(effect_info->override_wininv, effect_info->override_winmat);
+
+ DRW_viewport_matrix_override_set(effect_info->override_persmat, DRW_MAT_PERS);
+ DRW_viewport_matrix_override_set(effect_info->override_persinv, DRW_MAT_PERSINV);
+ DRW_viewport_matrix_override_set(effect_info->override_winmat, DRW_MAT_WIN);
+ DRW_viewport_matrix_override_set(effect_info->override_wininv, DRW_MAT_WININV);
+
+ /* weight the mix factor by the jitter index */
+ effect_info->taa_mix_factor = mix_factor;
+}
+
+void workbench_taa_draw_scene_end(WORKBENCH_Data *vedata)
+{
+ /*
+ * If first frame than the offset is 0.0 and its depth is the depth buffer to use
+ * for the rest of the draw engines. We store it in a persistent buffer.
+ *
+ * If it is not the first frame we copy the persistent buffer back to the
+ * default depth buffer
+ */
+ const WORKBENCH_StorageList *stl = vedata->stl;
+ const WORKBENCH_EffectInfo *effect_info = stl->effects;
+ const WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ const DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+
+ if (effect_info->jitter_index == 1)
+ {
+ GPU_framebuffer_blit(dfbl->depth_only_fb, 0, fbl->depth_buffer_fb, 0, GPU_DEPTH_BIT);
+ }
+ else {
+ GPU_framebuffer_blit(fbl->depth_buffer_fb, 0, dfbl->depth_only_fb, 0, GPU_DEPTH_BIT);
+ }
+
+
+
+ DRW_viewport_matrix_override_unset_all();
+}
+
+void workbench_taa_draw_pass(WORKBENCH_EffectInfo *effect_info, DRWPass *pass)
+{
+ GPU_framebuffer_bind(effect_info->final_color_fb);
+ DRW_draw_pass(pass);
+
+ copy_m4_m4(effect_info->last_mat, effect_info->curr_mat);
+ if (effect_info->jitter_index != 0)
+ {
+ DRW_viewport_request_redraw();
+ }
+}
+
+void workbench_taa_view_updated(WORKBENCH_Data *vedata)
+{
+ WORKBENCH_EffectInfo *effect_info = vedata->stl->effects;
+ effect_info->view_updated = true;
+}
diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c
index 9f23cd5b43b..dd57bec05f6 100644
--- a/source/blender/draw/engines/workbench/workbench_forward.c
+++ b/source/blender/draw/engines/workbench/workbench_forward.c
@@ -58,12 +58,15 @@ static struct {
struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */
struct GPUTexture *transparent_revealage_tx; /* ref only, not alloced */
struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */
+ struct GPUTexture *effect_buffer_tx; /* ref only, not alloced */
+
int next_object_id;
float normal_world_matrix[3][3];
} e_data = {{NULL}};
/* Shaders */
extern char datatoc_common_hair_lib_glsl[];
+
extern char datatoc_workbench_forward_composite_frag_glsl[];
extern char datatoc_workbench_forward_depth_frag_glsl[];
extern char datatoc_workbench_forward_transparent_accum_frag_glsl[];
@@ -259,6 +262,10 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
/* Alloc transient pointers */
stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
}
+ if (!stl->effects) {
+ stl->effects = MEM_mallocN(sizeof(*stl->effects), __func__);
+ workbench_effect_info_init(stl->effects);
+ }
WORKBENCH_PrivateData *wpd = stl->g_data;
workbench_private_data_init(wpd);
float light_direction[3];
@@ -280,6 +287,8 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
forward_vert, NULL,
forward_depth_frag, defines_hair);
+ workbench_fxaa_engine_init();
+
e_data.checker_depth_sh = DRW_shader_create_fullscreen(
datatoc_workbench_checkerboard_depth_frag_glsl, NULL);
MEM_freeN(forward_vert);
@@ -300,6 +309,8 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
size[0], size[1], GPU_R16F, &draw_engine_workbench_transparent);
e_data.composite_buffer_tx = DRW_texture_pool_query_2D(
size[0], size[1], GPU_R11F_G11F_B10F, &draw_engine_workbench_transparent);
+ e_data.effect_buffer_tx = DRW_texture_pool_query_2D(
+ size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
GPU_framebuffer_ensure_config(&fbl->object_outline_fb, {
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
@@ -316,6 +327,10 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx),
});
+ GPU_framebuffer_ensure_config(&fbl->effect_fb, {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(e_data.effect_buffer_tx),
+ });
/* Transparency Accum */
{
@@ -342,6 +357,11 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata)
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
+
+ {
+ psl->effect_aa_pass = workbench_fxaa_create_pass(&e_data.effect_buffer_tx);
+ }
+
/* Checker Depth */
{
int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS;
@@ -361,6 +381,8 @@ void workbench_forward_engine_free()
DRW_SHADER_FREE_SAFE(e_data.object_outline_sh);
DRW_SHADER_FREE_SAFE(e_data.object_outline_hair_sh);
DRW_SHADER_FREE_SAFE(e_data.checker_depth_sh);
+
+ workbench_fxaa_engine_free();
}
void workbench_forward_cache_init(WORKBENCH_Data *UNUSED(vedata))
@@ -585,9 +607,9 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata)
DRW_draw_pass(psl->composite_pass);
/* Color correct */
- GPU_framebuffer_bind(dfbl->color_only_fb);
- DRW_transform_to_display(e_data.composite_buffer_tx);
+ workbench_fxaa_draw_pass(wpd, fbl->effect_fb, e_data.composite_buffer_tx, psl->effect_aa_pass);
+ /* Apply checker pattern */
GPU_framebuffer_bind(dfbl->depth_only_fb);
DRW_draw_pass(psl->checker_depth_pass);
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 57cfd6b4718..404ec50fd97 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -50,7 +50,12 @@
#define STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd) (MATCAP_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_ORIENTATION_VIEWNORMAL))
#define CAVITY_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_CAVITY)
#define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW)
-#define FXAA_ENABLED(wpd) (wpd->user_preferences->gpu_viewport_antialias & USER_AA_FXAA && (!DRW_state_is_opengl_render()))
+
+#define IS_NAVIGATING(wpd) (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING)
+#define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && ((wpd->user_preferences->gpu_viewport_antialias == USER_AA_FXAA) || (ELEM(wpd->user_preferences->gpu_viewport_antialias, USER_AA_TAA8) && IS_NAVIGATING(wpd))))
+#define TAA8_ENABLED(wpd) (ELEM(wpd->user_preferences->gpu_viewport_antialias, USER_AA_TAA8) && (!DRW_state_is_opengl_render()) && (!IS_NAVIGATING(wpd)))
+#define TAA_ENABLED(wpd) (TAA8_ENABLED(wpd))
+
#define SPECULAR_HIGHLIGHT_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_ORIENTATION_VIEWNORMAL_ENABLED(wpd)))
#define OBJECT_ID_PASS_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
#define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED(wpd))
@@ -64,7 +69,11 @@ typedef struct WORKBENCH_FramebufferList {
struct GPUFrameBuffer *prepass_fb;
struct GPUFrameBuffer *cavity_fb;
struct GPUFrameBuffer *composite_fb;
+
struct GPUFrameBuffer *effect_fb;
+ struct GPUFrameBuffer *effect_taa_even_fb;
+ struct GPUFrameBuffer *effect_taa_uneven_fb;
+ struct GPUFrameBuffer *depth_buffer_fb;
/* Forward render buffers */
struct GPUFrameBuffer *object_outline_fb;
@@ -72,8 +81,15 @@ typedef struct WORKBENCH_FramebufferList {
struct GPUFrameBuffer *transparent_revealage_fb;
} WORKBENCH_FramebufferList;
+typedef struct WORKBENCH_TextureList {
+ struct GPUTexture *history_buffer1_tx;
+ struct GPUTexture *history_buffer2_tx;
+ struct GPUTexture *depth_buffer_tx;
+} WORKBENCH_TextureList;
+
typedef struct WORKBENCH_StorageList {
struct WORKBENCH_PrivateData *g_data;
+ struct WORKBENCH_EffectInfo *effects;
} WORKBENCH_StorageList;
typedef struct WORKBENCH_PassList {
@@ -89,7 +105,7 @@ typedef struct WORKBENCH_PassList {
struct DRWPass *shadow_depth_fail_caps_mani_pass;
struct DRWPass *composite_pass;
struct DRWPass *composite_shadow_pass;
- struct DRWPass *effect_fxaa_pass;
+ struct DRWPass *effect_aa_pass;
/* forward rendering */
struct DRWPass *transparent_accum_pass;
@@ -101,7 +117,7 @@ typedef struct WORKBENCH_PassList {
typedef struct WORKBENCH_Data {
void *engine_type;
WORKBENCH_FramebufferList *fbl;
- DRWViewportEmptyList *txl;
+ WORKBENCH_TextureList *txl;
WORKBENCH_PassList *psl;
WORKBENCH_StorageList *stl;
} WORKBENCH_Data;
@@ -171,6 +187,22 @@ typedef struct WORKBENCH_PrivateData {
float ssao_settings[4];
} WORKBENCH_PrivateData; /* Transient data */
+typedef struct WORKBENCH_EffectInfo {
+ float override_persmat[4][4];
+ float override_persinv[4][4];
+ float override_winmat[4][4];
+ float override_wininv[4][4];
+ float last_mat[4][4];
+ float curr_mat[4][4];
+ int jitter_index;
+ float taa_mix_factor;
+ bool view_updated;
+
+ /* The TX that holds the last color data */
+ struct GPUTexture *final_color_tx;
+ struct GPUFrameBuffer *final_color_fb;
+} WORKBENCH_EffectInfo;
+
typedef struct WORKBENCH_MaterialData {
/* Solid color */
WORKBENCH_UBO_Material material_data;
@@ -228,6 +260,21 @@ void workbench_forward_cache_init(WORKBENCH_Data *vedata);
void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob);
void workbench_forward_cache_finish(WORKBENCH_Data *vedata);
+/* workbench_effect_fxaa.c */
+void workbench_fxaa_engine_init(void);
+void workbench_fxaa_engine_free(void);
+DRWPass *workbench_fxaa_create_pass(GPUTexture **color_buffer_tx);
+void workbench_fxaa_draw_pass(WORKBENCH_PrivateData *wpd, GPUFrameBuffer *fb, GPUTexture *tx, DRWPass *effect_aa_pass);
+
+/* workbench_effect_taa.c */
+void workbench_taa_engine_init(WORKBENCH_Data *vedata);
+void workbench_taa_engine_free(void);
+DRWPass *workbench_taa_create_pass(WORKBENCH_TextureList *txl, WORKBENCH_EffectInfo *effect_info, WORKBENCH_FramebufferList *fbl, GPUTexture **color_buffer_tx);
+void workbench_taa_draw_pass(WORKBENCH_EffectInfo *effect_info, /*WORKBENCH_PrivateData *wpd, , GPUFrameBuffer *fb, GPUTexture *tx, */DRWPass *effect_aa_pass);
+void workbench_taa_draw_scene_start(WORKBENCH_EffectInfo *effect_info);
+void workbench_taa_draw_scene_end(WORKBENCH_Data *vedata);
+void workbench_taa_view_updated(WORKBENCH_Data *vedata);
+
/* workbench_materials.c */
int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima);
char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
@@ -245,6 +292,7 @@ float studiolight_object_shadow_distance(WORKBENCH_PrivateData *wpd, Object *ob,
bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
/* workbench_data.c */
+void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info);
void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
void workbench_private_data_free(WORKBENCH_PrivateData *wpd);
void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float light_direction[3]);