[Bf-blender-cvs] [1ca1744c29e] master: Fix T70807: Weight Paint Overlay XRay

Jeroen Bakker noreply at git.blender.org
Thu Mar 26 13:35:53 CET 2020


Commit: 1ca1744c29e299f36a83506aec23d9bc99b6e48c
Author: Jeroen Bakker
Date:   Thu Mar 26 08:59:02 2020 +0100
Branches: master
https://developer.blender.org/rB1ca1744c29e299f36a83506aec23d9bc99b6e48c

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

===================================================================

M	source/blender/draw/engines/overlay/overlay_paint.c
M	source/blender/draw/engines/overlay/overlay_private.h

===================================================================

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];



More information about the Bf-blender-cvs mailing list