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
This commit is contained in:
Jeroen Bakker 2018-06-25 09:06:39 +02:00
parent c07f2bc891
commit cf8a059769
11 changed files with 439 additions and 45 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -836,8 +836,9 @@ typedef enum eOpenGL_SelectOptions {
/* max anti alias draw method UserDef.gpu_viewport_antialias */
typedef enum eOpenGL_AntiAliasMethod {
USER_AA_NONE = 0,
USER_AA_FXAA = 1,
USER_AA_NONE = 0,
USER_AA_FXAA = 1,
USER_AA_TAA8 = 2,
} eOpenGL_AntiAliasMethod;
/* text draw options

View File

@ -4174,8 +4174,9 @@ static void rna_def_userdef_system(BlenderRNA *brna)
};
static const EnumPropertyItem gpu_antialias_method_items[] = {
{USER_AA_NONE, "OFF", 0, "Off", "Disable Anti Alias in viewport"},
{USER_AA_FXAA, "FXAA", 0, "FXAA", "Use FXAA, a fast screenspace Anti Alias method"},
{USER_AA_NONE, "OFF", 0, "Off", "Disable Anti Alias in viewport"},
{USER_AA_FXAA, "FXAA", 0, "FXAA", "Use FXAA, a fast screenspace Anti Alias method"},
{USER_AA_TAA8, "TAA8", 0, "TAA 8x", "Use TAA with 8 samples when screen is static, when not static fallback to FXAA"},
{0, NULL, 0, NULL, NULL}
};