Eevee: Depth of Feild: Fix ringing issue of background objects

There was an issue caused by Antialiasing being done after DoF. Move TAA
after DOF and Motion Blur.

Also certain pixel with lower CoC would be spread all over the background
because the neighbooring pixel have higher CoC. So we need to apply some
bilateral filtering when downsampling. Currently we limit the influence of
neighbor pixels with a CoC inside the range [MaxCoC-2, MaxCoC].
This commit is contained in:
Clément Foucault 2018-09-09 23:24:06 +02:00
parent d69d68621f
commit 6b551c0b8c
Notes: blender-bot 2023-02-14 08:42:53 +01:00
Referenced by issue #56763, Removing driver variable crashes Blender
Referenced by issue #56740, Crash When operating with Spot Light Lapm
Referenced by issue #56746, Crash on delete cube, add monkey, delete monkey, add cube
Referenced by issue #56733, 2.8 Fill Area only fills visible area
5 changed files with 79 additions and 65 deletions

View File

@ -119,6 +119,25 @@ static void eevee_create_shader_downsample(void)
"#define COPY_DEPTH\n");
}
#define SETUP_BUFFER(tex, fb, fb_color) { \
DRW_texture_ensure_fullscreen_2D(&tex, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP); \
GPU_framebuffer_ensure_config(&fb, { \
GPU_ATTACHMENT_TEXTURE(dtxl->depth), \
GPU_ATTACHMENT_TEXTURE(tex), \
}); \
GPU_framebuffer_ensure_config(&fb_color, { \
GPU_ATTACHMENT_NONE, \
GPU_ATTACHMENT_TEXTURE(tex), \
}); \
}
#define CLEANUP_BUFFER(tex, fb, fb_color) { \
/* Cleanup to release memory */ \
DRW_TEXTURE_FREE_SAFE(tex); \
GPU_FRAMEBUFFER_FREE_SAFE(fb); \
GPU_FRAMEBUFFER_FREE_SAFE(fb_color); \
}
void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera)
{
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
@ -166,22 +185,10 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
* Ping Pong buffer
*/
if ((effects->enabled_effects & EFFECT_POST_BUFFER) != 0) {
DRW_texture_ensure_fullscreen_2D(&txl->color_post, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
GPU_framebuffer_ensure_config(&fbl->effect_fb, {
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_TEXTURE(txl->color_post),
});
GPU_framebuffer_ensure_config(&fbl->effect_color_fb, {
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(txl->color_post),
});
SETUP_BUFFER(txl->color_post, fbl->effect_fb, fbl->effect_color_fb);
}
else {
/* Cleanup to release memory */
DRW_TEXTURE_FREE_SAFE(txl->color_post);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->effect_fb);
CLEANUP_BUFFER(txl->color_post, fbl->effect_fb, fbl->effect_color_fb);
}
/**
@ -269,22 +276,17 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object
* Setup double buffer so we can access last frame as it was before post processes.
*/
if ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) {
DRW_texture_ensure_fullscreen_2D(&txl->color_double_buffer, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
GPU_framebuffer_ensure_config(&fbl->double_buffer_fb, {
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
GPU_ATTACHMENT_TEXTURE(txl->color_double_buffer)
});
GPU_framebuffer_ensure_config(&fbl->double_buffer_color_fb, {
GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(txl->color_double_buffer)
});
SETUP_BUFFER(txl->color_double_buffer, fbl->double_buffer_fb, fbl->double_buffer_color_fb);
}
else {
/* Cleanup to release memory */
DRW_TEXTURE_FREE_SAFE(txl->color_double_buffer);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->double_buffer_fb);
CLEANUP_BUFFER(txl->color_double_buffer, fbl->double_buffer_fb, fbl->double_buffer_color_fb);
}
if ((effects->enabled_effects & (EFFECT_TAA | EFFECT_TAA_REPROJECT)) != 0) {
SETUP_BUFFER(txl->taa_history, fbl->taa_history_fb, fbl->taa_history_color_fb);
}
else {
CLEANUP_BUFFER(txl->taa_history, fbl->taa_history_fb, fbl->taa_history_color_fb);
}
}
@ -500,26 +502,19 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
effects->source_buffer = txl->color; /* latest updated texture */
effects->target_buffer = fbl->effect_color_fb; /* next target to render to */
/* Temporal Anti-Aliasing MUST come first */
EEVEE_temporal_sampling_draw(vedata);
/* Post process stack (order matters) */
EEVEE_motion_blur_draw(vedata);
EEVEE_depth_of_field_draw(vedata);
EEVEE_temporal_sampling_draw(vedata);
EEVEE_bloom_draw(vedata);
/* Save the final texture and framebuffer for final transformation or read. */
effects->final_tx = effects->source_buffer;
effects->final_fb = (effects->target_buffer != fbl->main_color_fb) ? fbl->main_fb : fbl->effect_fb;
if ((effects->enabled_effects & EFFECT_TAA) &&
(effects->enabled_effects & (EFFECT_BLOOM | EFFECT_DOF | EFFECT_MOTION_BLUR)) == 0)
(effects->source_buffer == txl->taa_history))
{
if (!effects->swap_double_buffer) {
effects->final_fb = fbl->double_buffer_fb;
}
else {
effects->final_fb = fbl->main_fb;
}
effects->final_fb = fbl->taa_history_fb;
}
/* If no post processes is enabled, buffers are still not swapped, do it now. */
@ -540,6 +535,7 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
/* Update double buffer status if render mode. */
if (DRW_state_is_image_render()) {
stl->g_data->valid_double_buffer = (txl->color_double_buffer != NULL);
stl->g_data->valid_taa_history = (txl->taa_history != NULL);;
}
}

View File

@ -69,6 +69,7 @@ static void eevee_engine_init(void *ved)
stl->g_data->use_color_view_settings = USE_SCENE_LIGHT(v3d) || !LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d);
stl->g_data->background_alpha = DRW_state_draw_background() ? 1.0f : 0.0f;
stl->g_data->valid_double_buffer = (txl->color_double_buffer != NULL);
stl->g_data->valid_taa_history = (txl->taa_history != NULL);
/* Main Buffer */
DRW_texture_ensure_fullscreen_2D(&txl->color, GPU_RGBA16F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);

View File

@ -95,6 +95,23 @@ extern struct DrawEngineType draw_engine_eevee_type;
} \
} ((void)0)
#define SWAP_BUFFERS_TAA() { \
if (effects->target_buffer == fbl->effect_color_fb) { \
SWAP(struct GPUFrameBuffer *, fbl->effect_fb, fbl->taa_history_fb); \
SWAP(struct GPUFrameBuffer *, fbl->effect_color_fb, fbl->taa_history_color_fb); \
SWAP(GPUTexture *, txl->color_post, txl->taa_history); \
effects->source_buffer = txl->taa_history; \
effects->target_buffer = fbl->effect_color_fb; \
} \
else { \
SWAP(struct GPUFrameBuffer *, fbl->main_fb, fbl->taa_history_fb); \
SWAP(struct GPUFrameBuffer *, fbl->main_color_fb, fbl->taa_history_color_fb); \
SWAP(GPUTexture *, txl->color, txl->taa_history); \
effects->source_buffer = txl->taa_history; \
effects->target_buffer = fbl->main_color_fb; \
} \
} ((void)0)
#define OVERLAY_ENABLED(v3d) ((v3d) && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)
#define LOOK_DEV_MODE_ENABLED(v3d) ((v3d) && (v3d->shading.type == OB_MATERIAL))
#define LOOK_DEV_OVERLAY_ENABLED(v3d) (LOOK_DEV_MODE_ENABLED(v3d) && OVERLAY_ENABLED(v3d) && (v3d->overlay.flag & V3D_OVERLAY_LOOK_DEV))
@ -280,6 +297,8 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *double_buffer_fb;
struct GPUFrameBuffer *double_buffer_color_fb;
struct GPUFrameBuffer *double_buffer_depth_fb;
struct GPUFrameBuffer *taa_history_fb;
struct GPUFrameBuffer *taa_history_color_fb;
} EEVEE_FramebufferList;
typedef struct EEVEE_TextureList {
@ -290,6 +309,7 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *sss_dir_accum;
struct GPUTexture *sss_col_accum;
struct GPUTexture *refract_color;
struct GPUTexture *taa_history;
struct GPUTexture *volume_prop_scattering;
struct GPUTexture *volume_prop_extinction;
@ -766,6 +786,7 @@ typedef struct EEVEE_PrivateData {
/* For double buffering */
bool view_updated;
bool valid_double_buffer;
bool valid_taa_history;
/* Render Matrices */
float persmat[4][4], persinv[4][4];
float viewmat[4][4], viewinv[4][4];

View File

@ -297,8 +297,8 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data
psl->taa_resolve = DRW_pass_create("Temporal AA Resolve", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->taa_resolve);
DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->color_double_buffer);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &txl->color);
DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->taa_history);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
if (effects->enabled_effects & EFFECT_TAA_REPROJECT) {
@ -312,16 +312,6 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data
}
}
/* Special Swap */
#define SWAP_BUFFER_TAA() do { \
SWAP(struct GPUFrameBuffer *, fbl->effect_fb, fbl->double_buffer_fb); \
SWAP(struct GPUFrameBuffer *, fbl->effect_color_fb, fbl->double_buffer_color_fb); \
SWAP(GPUTexture *, txl->color_post, txl->color_double_buffer); \
effects->swap_double_buffer = false; \
effects->source_buffer = txl->color_double_buffer; \
effects->target_buffer = fbl->main_color_fb; \
} while (0);
void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
@ -340,7 +330,7 @@ void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata)
effects->taa_alpha = 1.0f / (float)(effects->taa_current_sample);
}
GPU_framebuffer_bind(fbl->effect_color_fb);
GPU_framebuffer_bind(effects->target_buffer);
DRW_draw_pass(psl->taa_resolve);
/* Restore the depth from sample 1. */
@ -348,26 +338,30 @@ void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata)
GPU_framebuffer_blit(fbl->double_buffer_depth_fb, 0, fbl->main_fb, 0, GPU_DEPTH_BIT);
}
SWAP_BUFFER_TAA();
SWAP_BUFFERS_TAA();
}
else {
if (!DRW_state_is_image_render()) {
/* Do reprojection for noise reduction */
/* TODO : do AA jitter if in only render view. */
if ((effects->enabled_effects & EFFECT_TAA_REPROJECT) != 0 &&
stl->g_data->valid_double_buffer)
{
GPU_framebuffer_bind(fbl->effect_color_fb);
DRW_draw_pass(psl->taa_resolve);
SWAP_BUFFER_TAA();
}
/* Save the depth buffer for the next frame.
* This saves us from doing anything special
* in the other mode engines. */
GPU_framebuffer_blit(fbl->main_fb, 0, fbl->double_buffer_depth_fb, 0, GPU_DEPTH_BIT);
}
/* Do reprojection for noise reduction */
/* TODO : do AA jitter if in only render view. */
if (!DRW_state_is_image_render() &&
(effects->enabled_effects & EFFECT_TAA_REPROJECT) != 0 &&
stl->g_data->valid_taa_history)
{
GPU_framebuffer_bind(effects->target_buffer);
DRW_draw_pass(psl->taa_resolve);
SWAP_BUFFERS_TAA();
}
else {
struct GPUFrameBuffer *source_fb = (effects->target_buffer == fbl->main_color_fb) ? fbl->effect_color_fb : fbl->main_color_fb;
GPU_framebuffer_blit(source_fb, 0, fbl->taa_history_color_fb, 0, GPU_COLOR_BIT);
}
}
/* Make each loop count when doing a render. */

View File

@ -36,6 +36,7 @@ uniform vec2 nearFar; /* Near & far view depths values */
float max_v4(vec4 v) { return max(max(v.x, v.y), max(v.z, v.w)); }
#define THRESHOLD 0.0
#define SIMILAR_COC_THRESHOLD 2.0
#ifdef STEP_DOWNSAMPLE
@ -70,8 +71,9 @@ void main(void)
vec4 coc_far = -coc_near;
/* now we need to write the near-far fields premultiplied by the coc */
vec4 near_weights = step(THRESHOLD, coc_near);
vec4 far_weights = step(THRESHOLD, coc_far);
/* Also reject pixels that have a much lower coc than the max coc pixel. */
vec4 near_weights = step(THRESHOLD, coc_near) * step(max_v4(coc_near) - SIMILAR_COC_THRESHOLD, coc_near);
vec4 far_weights = step(THRESHOLD, coc_far) * step(max_v4(coc_far) - SIMILAR_COC_THRESHOLD, coc_far);
/* now write output to weighted buffers. */
nearColor = weighted_sum(color1, color2, color3, color4, near_weights);