Fix #120628: Transfer mode overlay flickering artifacts

Clear depth from Workbench when overlays are disabled.
Disable alpha blend and enable depth testing in the transfer mode
overlay so it works without a previously rendered depth buffer.

Pull Request: https://projects.blender.org/blender/blender/pulls/123729
This commit is contained in:
Miguel Pozo 2024-06-25 16:09:06 +02:00
parent 36060eda49
commit b8587c96ec
4 changed files with 14 additions and 2 deletions

@ -29,7 +29,7 @@ void OVERLAY_mode_transfer_cache_init(OVERLAY_Data *vedata)
for (int i = 0; i < 2; i++) {
/* Non Meshes Pass (Camera, empties, lights ...) */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH;
DRW_PASS_CREATE(psl->mode_transfer_ps[i], state | pd->clipping_state);
}
}
@ -105,6 +105,8 @@ void OVERLAY_mode_transfer_cache_populate(OVERLAY_Data *vedata, Object *ob)
UI_GetThemeColor3fv(TH_VERTEX_SELECT, color);
color[3] = mode_transfer_alpha_for_animation_time_get(animation_time);
srgb_to_linearrgb_v4(color, color);
/* Alpha pre-multiply. */
mul_v3_fl(color, color[3]);
DRW_shgroup_uniform_vec4_copy(mode_transfer_grp[i], "ucolor", color);
}

@ -475,6 +475,15 @@ class Instance {
{
this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
if (!scene_state.overlays_enabled) {
resources.clear_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(depth_in_front_tx));
resources.clear_in_front_fb.bind();
GPU_framebuffer_clear_depth_stencil(resources.clear_in_front_fb, 1.0f, 0x00);
resources.clear_depth_only_fb.ensure(GPU_ATTACHMENT_TEXTURE(depth_tx));
resources.clear_depth_only_fb.bind();
GPU_framebuffer_clear_depth_stencil(resources.clear_depth_only_fb, 1.0f, 0x00);
}
if (scene_state.sample + 1 < scene_state.samples_len) {
DRW_viewport_request_redraw();
}

@ -281,6 +281,7 @@ struct SceneResources {
TextureRef depth_in_front_tx;
Framebuffer clear_fb = {"Clear Main"};
Framebuffer clear_depth_only_fb = {"Clear Depth"};
Framebuffer clear_in_front_fb = {"Clear In Front"};
StorageVectorBuffer<Material> material_buf = {"material_buf"};

@ -155,7 +155,7 @@ void SceneState::init(Object *camera_ob /*=nullptr*/)
bool _overlays_enabled = v3d && !(v3d->flag2 & V3D_HIDE_OVERLAYS);
/* Depth is always required in Wireframe mode. */
_overlays_enabled = _overlays_enabled || shading.type < OB_SOLID;
/* Some overlay passes can be rendered even with overlays disabled (See #116424). */
/* Some overlay passes can be rendered even with overlays disabled (See #116403). */
_overlays_enabled = _overlays_enabled || new_clip_state & DRW_STATE_CLIP_PLANES;
if (assign_if_different(overlays_enabled, _overlays_enabled)) {
/* Reset TAA when enabling overlays, since we won't have valid sample0 depth textures.