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)
This commit is contained in:
Jeroen Bakker 2018-06-28 14:09:48 +02:00
parent daa47e5e80
commit 2b4c7600b7
7 changed files with 125 additions and 77 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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_framebuffer_ensure_config(&fbl->effect_taa_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_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);

View File

@ -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);

View File

@ -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);