diff options
5 files changed, 78 insertions, 64 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 28658d5126c..f25a6cf68e8 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -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) - }); + SETUP_BUFFER(txl->color_double_buffer, fbl->double_buffer_fb, fbl->double_buffer_color_fb); + } + else { + CLEANUP_BUFFER(txl->color_double_buffer, fbl->double_buffer_fb, fbl->double_buffer_color_fb); + } - GPU_framebuffer_ensure_config(&fbl->double_buffer_color_fb, { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(txl->color_double_buffer) - }); + 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 to release memory */ - DRW_TEXTURE_FREE_SAFE(txl->color_double_buffer); - GPU_FRAMEBUFFER_FREE_SAFE(fbl->double_buffer_fb); + 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);; } } diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index c1e66033592..a5661581a1a 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -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); diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index bd1323dab3b..d5af5a3d8fe 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -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]; diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 6cb2d1d3b53..384fb28a776 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -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. */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl index 34d92fab2c2..4e47df04bd2 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl @@ -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); |