From 1ca1744c29e299f36a83506aec23d9bc99b6e48c Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 26 Mar 2020 08:59:02 +0100 Subject: Fix T70807: Weight Paint Overlay XRay Weight paint overlay was not working when XRay was turned on. The Weight Paint overlay is rendered directly into the default framebuffer with a depth equal test. This test fails as the depth won't match. This patch will update the depth buffer in these cases. Reviewed By: fclem Differential Revision: https://developer.blender.org/D7176 --- .../blender/draw/engines/overlay/overlay_paint.c | 60 +++++++++++++++++++--- .../blender/draw/engines/overlay/overlay_private.h | 3 ++ 2 files changed, 55 insertions(+), 8 deletions(-) (limited to 'source/blender/draw') diff --git a/source/blender/draw/engines/overlay/overlay_paint.c b/source/blender/draw/engines/overlay/overlay_paint.c index bb0b124f2ae..256cc0146dc 100644 --- a/source/blender/draw/engines/overlay/overlay_paint.c +++ b/source/blender/draw/engines/overlay/overlay_paint.c @@ -28,6 +28,33 @@ #include "overlay_private.h" +/* Check if the given object is rendered (partially) transparent */ +static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob) +{ + if (v3d->shading.type == OB_WIRE) { + return true; + } + else if (v3d->shading.type == OB_SOLID) { + if (v3d->shading.flag & V3D_SHADING_XRAY) { + return true; + } + + if (v3d->shading.color_type == V3D_SHADING_OBJECT_COLOR) { + return ob->color[3] < 1.0f; + } + else if (v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) { + Mesh *me = ob->data; + for (int i = 0; i < me->totcol; i++) { + Material *mat = me->mat[i]; + if (mat->a < 1.0f) { + return true; + } + } + } + } + return false; +} + void OVERLAY_paint_init(OVERLAY_Data *vedata) { OVERLAY_StorageList *stl = vedata->stl; @@ -35,6 +62,8 @@ void OVERLAY_paint_init(OVERLAY_Data *vedata) const DRWContextState *draw_ctx = DRW_context_state_get(); pd->painting.in_front = draw_ctx->obact && (draw_ctx->obact->dtx & OB_DRAWXRAY); + pd->painting.alpha_blending = paint_object_is_rendered_transparent(draw_ctx->v3d, + draw_ctx->obact); } void OVERLAY_paint_cache_init(OVERLAY_Data *vedata) @@ -46,9 +75,10 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata) DRWShadingGroup *grp; DRWState state; - const bool use_alpha_blending = (draw_ctx->v3d->shading.type == OB_WIRE); const bool draw_contours = (pd->overlay.wpaint_flag & V3D_OVERLAY_WPAINT_CONTOURS) != 0; float opacity = 0.0f; + pd->paint_depth_grp = NULL; + psl->paint_depth_ps = NULL; switch (pd->ctx_mode) { case CTX_MODE_POSE: @@ -56,16 +86,23 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata) opacity = pd->overlay.weight_paint_mode_opacity; if (opacity > 0.0f) { state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; - state |= use_alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL; + state |= pd->painting.alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL; DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state); sh = OVERLAY_shader_paint_weight(); pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_bool_copy(grp, "drawContours", draw_contours); - DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", use_alpha_blending); + DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", pd->painting.alpha_blending); DRW_shgroup_uniform_float_copy(grp, "opacity", opacity); DRW_shgroup_uniform_texture(grp, "colorramp", G_draw.weight_ramp); + + if (pd->painting.alpha_blending) { + state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; + DRW_PASS_CREATE(psl->paint_depth_ps, state); + sh = OVERLAY_shader_depth_only(); + pd->paint_depth_grp = DRW_shgroup_create(sh, psl->paint_depth_ps); + } } break; } @@ -73,13 +110,13 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata) opacity = pd->overlay.vertex_paint_mode_opacity; if (opacity > 0.0f) { state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; - state |= use_alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL; + state |= pd->painting.alpha_blending ? DRW_STATE_BLEND_ALPHA : DRW_STATE_BLEND_MUL; DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state); sh = OVERLAY_shader_paint_vertcol(); pd->paint_surf_grp = grp = DRW_shgroup_create(sh, psl->paint_color_ps); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", use_alpha_blending); + DRW_shgroup_uniform_bool_copy(grp, "useAlphaBlend", pd->painting.alpha_blending); DRW_shgroup_uniform_float_copy(grp, "opacity", opacity); } break; @@ -173,11 +210,15 @@ void OVERLAY_paint_vertex_cache_populate(OVERLAY_Data *vedata, Object *ob) const bool use_face_sel = (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_vert_sel = (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; - if (pd->paint_surf_grp) { - if (ob->mode == OB_MODE_WEIGHT_PAINT) { + if (ob->mode == OB_MODE_WEIGHT_PAINT) { + if (pd->paint_surf_grp) { geom = DRW_cache_mesh_surface_weights_get(ob); DRW_shgroup_call(pd->paint_surf_grp, geom, ob); } + if (pd->paint_depth_grp) { + geom = DRW_cache_mesh_surface_weights_get(ob); + DRW_shgroup_call(pd->paint_depth_grp, geom, ob); + } } if (use_face_sel || use_wire) { @@ -210,10 +251,13 @@ void OVERLAY_paint_draw(OVERLAY_Data *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (DRW_state_is_fbo()) { - /* Pain overlay needs final color because of multiply blend mode. */ + /* Paint overlay needs final color because of multiply blend mode. */ GPU_framebuffer_bind(pd->painting.in_front ? dfbl->in_front_fb : dfbl->default_fb); } + if (psl->paint_depth_ps) { + DRW_draw_pass(psl->paint_depth_ps); + } if (psl->paint_color_ps) { DRW_draw_pass(psl->paint_color_ps); } diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h index 47c52c885b2..7cc83c76857 100644 --- a/source/blender/draw/engines/overlay/overlay_private.h +++ b/source/blender/draw/engines/overlay/overlay_private.h @@ -93,6 +93,7 @@ typedef struct OVERLAY_PassList { DRWPass *outlines_detect_ps; DRWPass *outlines_resolve_ps; DRWPass *paint_color_ps; + DRWPass *paint_depth_ps; DRWPass *paint_overlay_ps; DRWPass *particle_ps; DRWPass *pointcloud_ps; @@ -245,6 +246,7 @@ typedef struct OVERLAY_PrivateData { DRWShadingGroup *motion_path_points_grp; DRWShadingGroup *outlines_grp; DRWShadingGroup *outlines_gpencil_grp; + DRWShadingGroup *paint_depth_grp; DRWShadingGroup *paint_surf_grp; DRWShadingGroup *paint_wire_grp; DRWShadingGroup *paint_wire_selected_grp; @@ -318,6 +320,7 @@ typedef struct OVERLAY_PrivateData { } armature; struct { bool in_front; + bool alpha_blending; } painting; struct { DRWCallBuffer *handle[2]; -- cgit v1.2.3