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:
parent
c07f2bc891
commit
cf8a059769
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue