[Bf-blender-cvs] [e82827bf6ed] master: DRW: New High Quality Normal & Tangent extract

Clément Foucault noreply at git.blender.org
Wed Feb 19 01:58:49 CET 2020


Commit: e82827bf6ed54a1d1552ac9176df9e309b4d29e2
Author: Clément Foucault
Date:   Wed Feb 19 01:44:52 2020 +0100
Branches: master
https://developer.blender.org/rBe82827bf6ed54a1d1552ac9176df9e309b4d29e2

DRW: New High Quality Normal & Tangent extract

This patch adds a dedicated path to extract 16bit normals instead of packing them into 10bits/comp.
The tangents are also packed to 10bits/comp if not using the new High Quality Normal option.

Fix T61024 Degraded texture shading on dense meshes

Reviewed By: brecht

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

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

M	release/scripts/startup/bl_ui/properties_render.py
M	source/blender/draw/intern/draw_cache_extract.h
M	source/blender/draw/intern/draw_cache_extract_mesh.c
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index b4c864c16cd..9c422b58ee5 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -524,6 +524,25 @@ class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel):
         layout.prop(rd, "hair_subdiv")
 
 
+class RENDER_PT_eevee_performance(RenderButtonsPanel, Panel):
+    bl_label = "Performance"
+    bl_options = {'DEFAULT_CLOSED'}
+    COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
+
+    @classmethod
+    def poll(cls, context):
+        return (context.engine in cls.COMPAT_ENGINES)
+
+    def draw(self, context):
+        layout = self.layout
+        scene = context.scene
+        rd = scene.render
+
+        layout.use_property_split = True
+
+        layout.prop(rd, "use_high_quality_normals")
+
+
 class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel):
     bl_label = "Sampling"
     COMPAT_ENGINES = {'BLENDER_WORKBENCH'}
@@ -674,6 +693,7 @@ classes = (
     RENDER_PT_eevee_volumetric,
     RENDER_PT_eevee_volumetric_lighting,
     RENDER_PT_eevee_volumetric_shadows,
+    RENDER_PT_eevee_performance,
     RENDER_PT_eevee_hair,
     RENDER_PT_eevee_shadows,
     RENDER_PT_eevee_indirect_lighting,
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 9228147af44..6226b5dcf7f 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -253,6 +253,7 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache,
                                         const bool do_uvedit,
                                         const bool use_subsurf_fdots,
                                         const DRW_MeshCDMask *cd_layer_used,
+                                        const Scene *scene,
                                         const ToolSettings *ts,
                                         const bool use_hide);
 
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index 61a4a963cf9..edd7dee004c 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -1579,6 +1579,81 @@ static const MeshExtract extract_pos_nor = {
 };
 /** \} */
 
+/* ---------------------------------------------------------------------- */
+/** \name Extract HQ Loop Normal
+ * \{ */
+
+typedef struct gpuHQNor {
+  short x, y, z, w;
+} gpuHQNor;
+
+static void *extract_lnor_hq_init(const MeshRenderData *mr, void *buf)
+{
+  static GPUVertFormat format = {0};
+  if (format.attr_len == 0) {
+    GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+    GPU_vertformat_alias_add(&format, "lnor");
+  }
+  GPUVertBuf *vbo = buf;
+  GPU_vertbuf_init_with_format(vbo, &format);
+  GPU_vertbuf_data_alloc(vbo, mr->loop_len);
+
+  return vbo->data;
+}
+
+static void extract_lnor_hq_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *data)
+{
+  if (mr->loop_normals) {
+    normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->loop_normals[l]);
+  }
+  else if (BM_elem_flag_test(loop->f, BM_ELEM_SMOOTH)) {
+    normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, loop->v->no);
+  }
+  else {
+    normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, loop->f->no);
+  }
+}
+
+static void extract_lnor_hq_loop_mesh(
+    const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *data)
+{
+  if (mr->loop_normals) {
+    normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->loop_normals[l]);
+  }
+  else if (mpoly->flag & ME_SMOOTH) {
+    copy_v3_v3_short(&((gpuHQNor *)data)[l].x, mr->mvert[mloop->v].no);
+  }
+  else {
+    normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->poly_normals[p]);
+  }
+  /* Flag for paint mode overlay. */
+  if (mpoly->flag & ME_HIDE) {
+    ((gpuHQNor *)data)[l].w = -1;
+  }
+  else if (mpoly->flag & ME_FACE_SEL) {
+    ((gpuHQNor *)data)[l].w = 1;
+  }
+  else {
+    ((gpuHQNor *)data)[l].w = 0;
+  }
+}
+
+static const MeshExtract extract_lnor_hq = {
+    extract_lnor_hq_init,
+    NULL,
+    NULL,
+    extract_lnor_hq_loop_bmesh,
+    extract_lnor_hq_loop_mesh,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    MR_DATA_LOOP_NOR,
+    true,
+};
+
+/** \} */
 /* ---------------------------------------------------------------------- */
 /** \name Extract Loop Normal
  * \{ */
@@ -1762,8 +1837,11 @@ static const MeshExtract extract_uv = {
 /** \name Extract Tangent layers
  * \{ */
 
-static void *extract_tan_init(const MeshRenderData *mr, void *buf)
+static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool do_hq)
 {
+  GPUVertCompType comp_type = do_hq ? GPU_COMP_F32 : GPU_COMP_I10;
+  GPUVertFetchMode fetch_mode = do_hq ? GPU_FETCH_FLOAT : GPU_FETCH_INT_TO_FLOAT_UNIT;
+
   GPUVertFormat format = {0};
   GPU_vertformat_deinterleave(&format);
 
@@ -1784,7 +1862,7 @@ static void *extract_tan_init(const MeshRenderData *mr, void *buf)
       GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
       /* Tangent layer name. */
       BLI_snprintf(attr_name, sizeof(attr_name), "t%s", attr_safe_name);
-      GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+      GPU_vertformat_attr_add(&format, attr_name, comp_type, 4, fetch_mode);
       /* Active render layer name. */
       if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) {
         GPU_vertformat_alias_add(&format, "t");
@@ -1860,7 +1938,7 @@ static void *extract_tan_init(const MeshRenderData *mr, void *buf)
     const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_TANGENT, 0);
     GPU_vertformat_safe_attrib_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTRIB_NAME);
     BLI_snprintf(attr_name, sizeof(*attr_name), "t%s", attr_safe_name);
-    GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+    GPU_vertformat_attr_add(&format, attr_name, comp_type, 4, fetch_mode);
     GPU_vertformat_alias_add(&format, "t");
     GPU_vertformat_alias_add(&format, "at");
   }
@@ -1876,23 +1954,56 @@ static void *extract_tan_init(const MeshRenderData *mr, void *buf)
     v_len = 1;
   }
 
-  GPUVertBuf *vbo = buf;
   GPU_vertbuf_init_with_format(vbo, &format);
   GPU_vertbuf_data_alloc(vbo, v_len);
 
-  float(*tan_data)[4] = (float(*)[4])vbo->data;
-  for (int i = 0; i < tan_len; i++) {
-    void *layer_data = CustomData_get_layer_named(cd_ldata, CD_TANGENT, tangent_names[i]);
-    memcpy(tan_data, layer_data, sizeof(*tan_data) * mr->loop_len);
-    tan_data += mr->loop_len;
+  if (do_hq) {
+    short(*tan_data)[4] = (short(*)[4])vbo->data;
+    for (int i = 0; i < tan_len; i++) {
+      const char *name = tangent_names[i];
+      float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(cd_ldata, CD_TANGENT, name);
+      for (int l = 0; l < mr->loop_len; l++) {
+        normal_float_to_short_v3(*tan_data, layer_data[l]);
+        (*tan_data)[3] = (layer_data[l][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
+        tan_data++;
+      }
+    }
+    if (use_orco_tan) {
+      float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(cd_ldata, CD_TANGENT, 0);
+      for (int l = 0; l < mr->loop_len; l++) {
+        normal_float_to_short_v3(*tan_data, layer_data[l]);
+        (*tan_data)[3] = (layer_data[l][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
+        tan_data++;
+      }
+    }
   }
-  if (use_orco_tan) {
-    void *layer_data = CustomData_get_layer_n(cd_ldata, CD_TANGENT, 0);
-    memcpy(tan_data, layer_data, sizeof(*tan_data) * mr->loop_len);
+  else {
+    GPUPackedNormal *tan_data = (GPUPackedNormal *)vbo->data;
+    for (int i = 0; i < tan_len; i++) {
+      const char *name = tangent_names[i];
+      float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(cd_ldata, CD_TANGENT, name);
+      for (int l = 0; l < mr->loop_len; l++) {
+        *tan_data = GPU_normal_convert_i10_v3(layer_data[l]);
+        tan_data->w = (layer_data[l][3] > 0.0f) ? 1 : -2;
+        tan_data++;
+      }
+    }
+    if (use_orco_tan) {
+      float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(cd_ldata, CD_TANGENT, 0);
+      for (int l = 0; l < mr->loop_len; l++) {
+        *tan_data = GPU_normal_convert_i10_v3(layer_data[l]);
+        tan_data->w = (layer_data[l][3] > 0.0f) ? 1 : -2;
+        tan_data++;
+      }
+    }
   }
 
   CustomData_free_layers(cd_ldata, CD_TANGENT, mr->loop_len);
+}
 
+static void *extract_tan_init(const MeshRenderData *mr, void *buf)
+{
+  extract_tan_ex(mr, buf, false);
   return NULL;
 }
 
@@ -1913,6 +2024,33 @@ static const MeshExtract extract_tan = {
 
 /** \} */
 
+/* ---------------------------------------------------------------------- */
+/** \name Extract HQ Tangent layers
+ * \{ */
+
+static void *extract_tan_hq_init(const MeshRenderData *mr, void *buf)
+{
+  extract_tan_ex(mr, buf, true);
+  return NULL;
+}
+
+static const MeshExtract extract_tan_hq = {
+    extract_tan_hq_init,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    MR_DATA_POLY_NOR | MR_DATA_TAN_LOOP_NOR | MR_DATA_LOOPTRI,
+    false,
+};
+
+/** \} */
+
 /* ---------------------------------------------------------------------- */
 /** \name Extract VCol
  * \{ */
@@ -4354,11 +4492,20 @@ static void extract_range_task_create(
 }
 
 static void extract_task_create(TaskPool *task_pool,
+                                const Scene *scene,
                                 const MeshRenderData *mr,
                                 const MeshExtract *extract,
                                 void *buf,
                                 int32_t *task_counter)
 {
+  const bool do_hq_normals = (scene->r.perf_flag & SCE_PERF_HQ_NORMALS) != 0;
+  if (do_hq_normals && (extract == &extract_lnor)) {
+    extract = &extract_lnor_hq;
+  }
+  if (do_hq_normals && (extract == &extract_tan)) {
+    extract = &extract_tan_hq;
+  }
+
   /* Divide extraction of the VBO/IBO into sensible chunks of works. */
   ExtractTaskData *taskdata = MEM_mal

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list