[Bf-blender-cvs] [e2e2a98573e] master: Fix T73518: Normal Overlay

Jeroen Bakker noreply at git.blender.org
Mon Feb 17 15:00:35 CET 2020


Commit: e2e2a98573e060cf26ab5141550dcd64838afc40
Author: Jeroen Bakker
Date:   Mon Feb 10 15:29:16 2020 +0100
Branches: master
https://developer.blender.org/rBe2e2a98573e060cf26ab5141550dcd64838afc40

Fix T73518: Normal Overlay

This change will not render the normals for faces that are hidden.
Before we had instance drawing the hidden faces were registered in the
index buffer. During the overlay refactoring the rendering was migrated
to instance rendering. Instance rendering does not use the index buffer
so the data was ignored.

This patch stored the normal visibility in the .w part of the normal or
for face normals it will set the normal to zero. The shader looks at
this and renders the normals fully transparent when detected.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D6798

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

M	source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl
M	source/blender/draw/intern/draw_cache_extract_mesh.c

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

diff --git a/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl
index 2a00160836b..8833490e818 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_mesh_normal_vert.glsl
@@ -4,8 +4,8 @@ uniform sampler2D depthTex;
 uniform float alpha = 1.0;
 
 in vec3 pos;
-in vec3 lnor;
-in vec3 vnor;
+in vec4 lnor;
+in vec4 vnor;
 in vec4 norAndFlag;
 
 flat out vec4 finalColor;
@@ -22,16 +22,28 @@ void main()
 
   vec3 nor;
   /* Select the right normal by cheking if the generic attrib is used.  */
-  if (!all(equal(lnor, vec3(0)))) {
-    nor = lnor;
+  if (!all(equal(lnor.xyz, vec3(0)))) {
+    if (lnor.w < 0.0) {
+      finalColor = vec4(0.0);
+      return;
+    }
+    nor = lnor.xyz;
     finalColor = colorLNormal;
   }
-  else if (!all(equal(vnor, vec3(0)))) {
-    nor = vnor;
+  else if (!all(equal(vnor.xyz, vec3(0)))) {
+    if (vnor.w < 0.0) {
+      finalColor = vec4(0.0);
+      return;
+    }
+    nor = vnor.xyz;
     finalColor = colorVNormal;
   }
   else {
     nor = norAndFlag.xyz;
+    if (all(equal(nor, vec3(0.0)))) {
+      finalColor = vec4(0.0);
+      return;
+    }
     finalColor = colorNormal;
   }
 
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index ee0597c6b21..61a4a963cf9 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -1483,13 +1483,15 @@ static void extract_pos_nor_loop_bmesh(const MeshRenderData *UNUSED(mr),
   PosNorLoop *vert = data->vbo_data + l;
   copy_v3_v3(vert->pos, loop->v->co);
   vert->nor = data->packed_nor[BM_elem_index_get(loop->v)];
+  BMFace *efa = loop->f;
+  vert->nor.w = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0;
 }
 
 static void extract_pos_nor_loop_mesh(const MeshRenderData *mr,
                                       int l,
                                       const MLoop *mloop,
                                       int UNUSED(p),
-                                      const MPoly *UNUSED(mpoly),
+                                      const MPoly *mpoly,
                                       void *_data)
 {
   MeshExtract_PosNor_Data *data = _data;
@@ -1498,7 +1500,7 @@ static void extract_pos_nor_loop_mesh(const MeshRenderData *mr,
   copy_v3_v3(vert->pos, mvert->co);
   vert->nor = data->packed_nor[mloop->v];
   /* Flag for paint mode overlay. */
-  if (mvert->flag & ME_HIDE) {
+  if (mpoly->flag & ME_HIDE || mvert->flag & ME_HIDE) {
     vert->nor.w = -1;
   }
   else if (mvert->flag & SELECT) {
@@ -1606,6 +1608,8 @@ static void extract_lnor_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loo
   else {
     ((GPUPackedNormal *)data)[l] = GPU_normal_convert_i10_v3(loop->f->no);
   }
+  BMFace *efa = loop->f;
+  ((GPUPackedNormal *)data)[l].w = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0;
 }
 
 static void extract_lnor_loop_mesh(
@@ -3711,6 +3715,10 @@ static const MeshExtract extract_fdots_pos = {
 /* ---------------------------------------------------------------------- */
 /** \name Extract Facedots Normal and edit flag
  * \{ */
+#define NOR_AND_FLAG_DEFAULT 0
+#define NOR_AND_FLAG_SELECT 1
+#define NOR_AND_FLAG_ACTIVE -1
+#define NOR_AND_FLAG_HIDDEN -2
 
 static void *extract_fdots_nor_init(const MeshRenderData *mr, void *buf)
 {
@@ -3727,6 +3735,7 @@ static void *extract_fdots_nor_init(const MeshRenderData *mr, void *buf)
 
 static void extract_fdots_nor_finish(const MeshRenderData *mr, void *buf, void *UNUSED(data))
 {
+  static float invalid_normal[3] = {0.0f, 0.0f, 0.0f};
   GPUVertBuf *vbo = buf;
   GPUPackedNormal *nor = (GPUPackedNormal *)vbo->data;
   BMFace *efa;
@@ -3735,17 +3744,33 @@ static void extract_fdots_nor_finish(const MeshRenderData *mr, void *buf, void *
   if (mr->extract_type == MR_EXTRACT_BMESH) {
     for (int f = 0; f < mr->poly_len; f++) {
       efa = BM_face_at_index(mr->bm, f);
-      nor[f] = GPU_normal_convert_i10_v3(efa->no);
-      /* Select / Active Flag. */
-      nor[f].w = BM_elem_flag_test(efa, BM_ELEM_SELECT) ? ((efa == mr->efa_act) ? -1 : 1) : 0;
+      const bool is_face_hidden = BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
+      if (is_face_hidden) {
+        nor[f] = GPU_normal_convert_i10_v3(invalid_normal);
+        nor[f].w = NOR_AND_FLAG_HIDDEN;
+      }
+      else {
+        nor[f] = GPU_normal_convert_i10_v3(efa->no);
+        /* Select / Active Flag. */
+        nor[f].w = (BM_elem_flag_test(efa, BM_ELEM_SELECT) ?
+                        ((efa == mr->efa_act) ? NOR_AND_FLAG_ACTIVE : NOR_AND_FLAG_SELECT) :
+                        NOR_AND_FLAG_DEFAULT);
+      }
     }
   }
   else {
     for (int f = 0; f < mr->poly_len; f++) {
-      nor[f] = GPU_normal_convert_i10_v3(mr->poly_normals[f]);
-      if ((efa = bm_original_face_get(mr, f))) {
+      efa = bm_original_face_get(mr, f);
+      if (!efa || BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+        nor[f] = GPU_normal_convert_i10_v3(invalid_normal);
+        nor[f].w = NOR_AND_FLAG_HIDDEN;
+      }
+      else {
+        nor[f] = GPU_normal_convert_i10_v3(efa->no);
         /* Select / Active Flag. */
-        nor[f].w = BM_elem_flag_test(efa, BM_ELEM_SELECT) ? ((efa == mr->efa_act) ? -1 : 1) : 0;
+        nor[f].w = (BM_elem_flag_test(efa, BM_ELEM_SELECT) ?
+                        ((efa == mr->efa_act) ? NOR_AND_FLAG_ACTIVE : NOR_AND_FLAG_SELECT) :
+                        NOR_AND_FLAG_DEFAULT);
       }
     }
   }
@@ -4013,9 +4038,9 @@ static void *extract_select_idx_init(const MeshRenderData *mr, void *buf)
 }
 
 /* TODO Use glVertexID to get loop index and use the data structure on the CPU to retrieve the
- * select element associated with this loop ID. This would remove the need for this separate index
- * VBOs. We could upload the p/e/v_origindex as a buffer texture and sample it inside the shader to
- * output original index. */
+ * select element associated with this loop ID. This would remove the need for this separate
+ * index VBOs. We could upload the p/e/v_origindex as a buffer texture and sample it inside the
+ * shader to output original index. */
 
 static void extract_poly_idx_loop_bmesh(const MeshRenderData *UNUSED(mr),
                                         int l,



More information about the Bf-blender-cvs mailing list