From 2b4c7600b763f252a0e7f54d80cd8e3005871f5e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 28 Jun 2018 14:09:48 +0200 Subject: Workbench: Anti-aliasing refactor - TAA is also enabled for Forward rendering - Uses less GPU memory (removed one history buffer) - TAA is done after the color management - consolidated the aa code between forward and deferred rendering (workbench_effects_aa.c) --- source/blender/draw/CMakeLists.txt | 1 + .../draw/engines/workbench/workbench_deferred.c | 24 +------ .../draw/engines/workbench/workbench_effect_aa.c | 75 ++++++++++++++++++++++ .../draw/engines/workbench/workbench_effect_fxaa.c | 16 ----- .../draw/engines/workbench/workbench_effect_taa.c | 57 ++++++++-------- .../draw/engines/workbench/workbench_forward.c | 14 ++-- .../draw/engines/workbench/workbench_private.h | 15 ++--- 7 files changed, 125 insertions(+), 77 deletions(-) create mode 100644 source/blender/draw/engines/workbench/workbench_effect_aa.c (limited to 'source') diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index a68ccc0da93..d7b7129114e 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -111,6 +111,7 @@ set(SRC engines/workbench/workbench_data.c engines/workbench/workbench_engine.c engines/workbench/workbench_deferred.c + engines/workbench/workbench_effect_aa.c engines/workbench/workbench_effect_fxaa.c engines/workbench/workbench_effect_taa.c engines/workbench/workbench_forward.c diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index f2fb52d96d4..3b73154846f 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -410,16 +410,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata) } { - if (TAA_ENABLED(wpd)) { - psl->effect_aa_pass = workbench_taa_create_pass(vedata, &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; - } + workbench_aa_create_pass(vedata, &e_data.effect_buffer_tx); } { @@ -844,11 +835,9 @@ 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) { + if (TAA_ENABLED(wpd)) { workbench_taa_draw_scene_start(vedata); } @@ -886,13 +875,6 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata) DRW_draw_pass(psl->composite_pass); } - 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_aa_draw_pass(vedata, e_data.composite_buffer_tx); workbench_private_data_free(wpd); } diff --git a/source/blender/draw/engines/workbench/workbench_effect_aa.c b/source/blender/draw/engines/workbench/workbench_effect_aa.c new file mode 100644 index 00000000000..4f1ca7f561b --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_effect_aa.c @@ -0,0 +1,75 @@ +/* + * 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_aa.c + * \ingroup draw_engine + */ + +#include "workbench_private.h" + + +void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx) +{ + WORKBENCH_StorageList *stl = vedata->stl; + WORKBENCH_PrivateData *wpd = stl->g_data; + WORKBENCH_PassList *psl = vedata->psl; + WORKBENCH_EffectInfo *effect_info = stl->effects; + + if (TAA_ENABLED(wpd)) { + psl->effect_aa_pass = workbench_taa_create_pass(vedata, tx); + } + else if (FXAA_ENABLED(wpd)) { + psl->effect_aa_pass = workbench_fxaa_create_pass(tx); + effect_info->jitter_index = 0; + } + else { + psl->effect_aa_pass = NULL; + } +} + +void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx) +{ + WORKBENCH_StorageList *stl = vedata->stl; + WORKBENCH_PrivateData *wpd = stl->g_data; + WORKBENCH_FramebufferList *fbl = vedata->fbl; + WORKBENCH_PassList *psl = vedata->psl; + WORKBENCH_EffectInfo *effect_info = stl->effects; + + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + if (FXAA_ENABLED(wpd)) { + GPU_framebuffer_bind(fbl->effect_fb); + DRW_transform_to_display(tx); + GPU_framebuffer_bind(dfbl->color_only_fb); + DRW_draw_pass(psl->effect_aa_pass); + } + else if (TAA_ENABLED(wpd)) { + GPU_framebuffer_bind(fbl->effect_fb); + DRW_transform_to_display(tx); + + GPU_framebuffer_bind(dfbl->color_only_fb); + workbench_taa_draw_pass(effect_info, psl->effect_aa_pass); + workbench_taa_draw_scene_end(vedata); + } + else { + GPU_framebuffer_bind(dfbl->color_only_fb); + DRW_transform_to_display(tx); + } +} diff --git a/source/blender/draw/engines/workbench/workbench_effect_fxaa.c b/source/blender/draw/engines/workbench/workbench_effect_fxaa.c index 6b1d17d74cf..aeccb7646c7 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_fxaa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_fxaa.c @@ -56,22 +56,6 @@ DRWPass *workbench_fxaa_create_pass(GPUTexture **color_buffer_tx) 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 index 973ad6c6eab..43dfbd235b6 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_taa.c +++ b/source/blender/draw/engines/workbench/workbench_effect_taa.c @@ -1,3 +1,28 @@ +/* + * 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_taa.c + * \ingroup draw_engine + */ + #include "workbench_private.h" #include "BLI_jitter_2d.h" @@ -139,22 +164,16 @@ DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_bu * 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->history_buffer_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_framebuffer_ensure_config(&fbl->effect_taa_fb, { GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(txl->history_buffer2_tx), + GPU_ATTACHMENT_TEXTURE(txl->history_buffer_tx), }); GPU_framebuffer_ensure_config(&fbl->depth_buffer_fb, { GPU_ATTACHMENT_TEXTURE(txl->depth_buffer_tx), @@ -165,25 +184,10 @@ DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_bu 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_texture_ref(grp, "historyBuffer", &txl->history_buffer_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; - } - /* * Set the offset for the cavity shader so every iteration different * samples will be selected @@ -269,14 +273,13 @@ void workbench_taa_draw_scene_end(WORKBENCH_Data *vedata) GPU_framebuffer_blit(fbl->depth_buffer_fb, 0, dfbl->depth_only_fb, 0, GPU_DEPTH_BIT); } - + GPU_framebuffer_blit(dfbl->color_only_fb, 0, fbl->effect_taa_fb, 0, GPU_COLOR_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); diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index dd57bec05f6..41d16780d33 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -287,7 +287,6 @@ 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); @@ -296,6 +295,9 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) MEM_freeN(defines); MEM_freeN(defines_hair); } + workbench_fxaa_engine_init(); + workbench_taa_engine_init(vedata); + select_forward_shaders(wpd); const float *viewport_size = DRW_viewport_size_get(); @@ -359,7 +361,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) } { - psl->effect_aa_pass = workbench_fxaa_create_pass(&e_data.effect_buffer_tx); + workbench_aa_create_pass(vedata, &e_data.effect_buffer_tx); } /* Checker Depth */ @@ -582,6 +584,10 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata) WORKBENCH_PrivateData *wpd = stl->g_data; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + if (TAA_ENABLED(wpd)) { + workbench_taa_draw_scene_start(vedata); + } + /* Write Depth + Object ID */ const float clear_outline[4] = {0.0f}; GPU_framebuffer_bind(fbl->object_outline_fb); @@ -606,8 +612,8 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata) GPU_framebuffer_bind(fbl->composite_fb); DRW_draw_pass(psl->composite_pass); - /* Color correct */ - workbench_fxaa_draw_pass(wpd, fbl->effect_fb, e_data.composite_buffer_tx, psl->effect_aa_pass); + /* Color correct and Anti aliasing */ + workbench_aa_draw_pass(vedata, e_data.composite_buffer_tx); /* Apply checker pattern */ GPU_framebuffer_bind(dfbl->depth_only_fb); diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 5f938b8f0b2..5eb7631104d 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -69,8 +69,7 @@ typedef struct WORKBENCH_FramebufferList { struct GPUFrameBuffer *composite_fb; struct GPUFrameBuffer *effect_fb; - struct GPUFrameBuffer *effect_taa_even_fb; - struct GPUFrameBuffer *effect_taa_uneven_fb; + struct GPUFrameBuffer *effect_taa_fb; struct GPUFrameBuffer *depth_buffer_fb; /* Forward render buffers */ @@ -80,8 +79,7 @@ typedef struct WORKBENCH_FramebufferList { } WORKBENCH_FramebufferList; typedef struct WORKBENCH_TextureList { - struct GPUTexture *history_buffer1_tx; - struct GPUTexture *history_buffer2_tx; + struct GPUTexture *history_buffer_tx; struct GPUTexture *depth_buffer_tx; } WORKBENCH_TextureList; @@ -195,10 +193,6 @@ typedef struct WORKBENCH_EffectInfo { 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 { @@ -258,11 +252,14 @@ 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_aa.c */ +void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx); +void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx); + /* 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); -- cgit v1.2.3