[Bf-blender-cvs] [15350c70be8] blender-v2.82-release: DRW: Add support for tangent on objects using display lists.

Clément Foucault noreply at git.blender.org
Thu Jan 30 01:38:05 CET 2020


Commit: 15350c70be8befa661505f10c8151110bcbf2cb6
Author: Clément Foucault
Date:   Thu Jan 30 01:07:28 2020 +0100
Branches: blender-v2.82-release
https://developer.blender.org/rB15350c70be8befa661505f10c8151110bcbf2cb6

DRW: Add support for tangent on objects using display lists.

Only Metaballs are left unsupported.
However, the implementation does not match 100% with cycles which converts
all objects to meshes.

Fixes T63424 EEVEE: Normal map node doesn't works with curve objects

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

M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_curve.c
M	source/blender/draw/intern/draw_cache_impl_displist.c

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

diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 2970314db64..e5a363f3115 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -98,9 +98,10 @@ struct GPUBatch *DRW_metaball_batch_cache_get_edge_detection(struct Object *ob,
 /* DispList */
 void DRW_displist_vertbuf_create_pos_and_nor(struct ListBase *lb, struct GPUVertBuf *vbo);
 void DRW_displist_vertbuf_create_wiredata(struct ListBase *lb, struct GPUVertBuf *vbo);
-void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(struct ListBase *lb,
-                                                         struct GPUVertBuf *vbo_pos_nor,
-                                                         struct GPUVertBuf *vbo_uv);
+void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(struct ListBase *lb,
+                                                                 struct GPUVertBuf *vbo_pos_nor,
+                                                                 struct GPUVertBuf *vbo_uv,
+                                                                 struct GPUVertBuf *vbo_tan);
 void DRW_displist_indexbuf_create_lines_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo);
 void DRW_displist_indexbuf_create_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo);
 void DRW_displist_indexbuf_create_triangles_loop_split_by_material(struct ListBase *lb,
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
index 05ec9bda642..85340fae35d 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -333,8 +333,7 @@ static void curve_cd_calc_used_gpu_layers(int *cd_layers,
           *cd_layers |= CD_MLOOPUV;
           break;
         case CD_TANGENT:
-          /* Currently unsupported */
-          // *cd_layers |= CD_TANGENT;
+          *cd_layers |= CD_TANGENT;
           break;
         case CD_MCOL:
           /* Curve object don't have Color data. */
@@ -358,6 +357,7 @@ typedef struct CurveBatchCache {
 
     GPUVertBuf *loop_pos_nor;
     GPUVertBuf *loop_uv;
+    GPUVertBuf *loop_tan;
   } ordered;
 
   struct {
@@ -992,6 +992,9 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
       if (cache->cd_used & CD_MLOOPUV) {
         DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_uv);
       }
+      if (cache->cd_used & CD_TANGENT) {
+        DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_tan);
+      }
       DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_pos_nor);
     }
   }
@@ -1007,6 +1010,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
   DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.curves_pos, CU_DATATYPE_WIRE);
   DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_pos_nor, CU_DATATYPE_SURFACE);
   DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_uv, CU_DATATYPE_SURFACE);
+  DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_tan, CU_DATATYPE_SURFACE);
   DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surfaces_tris, CU_DATATYPE_SURFACE);
   DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surfaces_lines, CU_DATATYPE_SURFACE);
   DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.curves_lines, CU_DATATYPE_WIRE);
@@ -1045,8 +1049,8 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
 
   if (DRW_vbo_requested(cache->ordered.loop_pos_nor) ||
       DRW_vbo_requested(cache->ordered.loop_uv)) {
-    DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(
-        lb, cache->ordered.loop_pos_nor, cache->ordered.loop_uv);
+    DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(
+        lb, cache->ordered.loop_pos_nor, cache->ordered.loop_uv, cache->ordered.loop_tan);
   }
 
   if (DRW_ibo_requested(cache->surf_per_mat_tris[0])) {
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index eef108b1f2f..ad2495aa0d1 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -345,6 +345,8 @@ static void surf_uv_quad(const DispList *dl, const uint quad[4], float r_uv[4][2
   }
 
   for (int i = 0; i < 4; i++) {
+    /* Note: For some reason the shading U and V are swapped compared to the
+     * one described in the surface format. */
     /* find uv based on vertex index into grid array */
     r_uv[i][0] = (quad[i] / dl->nr) / (float)orco_sizev;
     r_uv[i][1] = (quad[i] % dl->nr) / (float)orco_sizeu;
@@ -359,15 +361,45 @@ static void surf_uv_quad(const DispList *dl, const uint quad[4], float r_uv[4][2
   }
 }
 
+static GPUPackedNormal surf_tan_quad(const DispList *dl,
+                                     const float (*verts)[3],
+                                     const float nor[3],
+                                     uint index)
+{
+  float tan[3], tmp[3];
+
+  int v = index / dl->nr;
+  /* Note: For some reason the shading U and V are swapped compared to the
+   * one described in the surface format. So tangent is along V. */
+  if (v == 0) {
+    sub_v3_v3v3(tan, verts[index + dl->nr], verts[index]);
+  }
+  else {
+    sub_v3_v3v3(tan, verts[index], verts[index - dl->nr]);
+  }
+  /* Orthonormalize around the normal. */
+  cross_v3_v3v3(tmp, nor, tan);
+  cross_v3_v3v3(tan, tmp, nor);
+  normalize_v3(tan);
+
+  GPUPackedNormal ptan = GPU_normal_convert_i10_v3(tan);
+  ptan.w = 1; /* Pretty sure surfaces cannot have inverted normals. */
+  return ptan;
+}
+
 static void displist_vertbuf_attr_set_tri_pos_nor_uv(GPUVertBufRaw *pos_step,
                                                      GPUVertBufRaw *nor_step,
                                                      GPUVertBufRaw *uv_step,
+                                                     GPUVertBufRaw *tan_step,
                                                      const float v1[3],
                                                      const float v2[3],
                                                      const float v3[3],
                                                      const GPUPackedNormal *n1,
                                                      const GPUPackedNormal *n2,
                                                      const GPUPackedNormal *n3,
+                                                     const GPUPackedNormal *t1,
+                                                     const GPUPackedNormal *t2,
+                                                     const GPUPackedNormal *t3,
                                                      const float uv1[2],
                                                      const float uv2[2],
                                                      const float uv3[2])
@@ -387,16 +419,24 @@ static void displist_vertbuf_attr_set_tri_pos_nor_uv(GPUVertBufRaw *pos_step,
     normal_float_to_short_v2(GPU_vertbuf_raw_step(uv_step), uv2);
     normal_float_to_short_v2(GPU_vertbuf_raw_step(uv_step), uv3);
   }
+
+  if (tan_step->size != 0) {
+    *(GPUPackedNormal *)GPU_vertbuf_raw_step(tan_step) = *t1;
+    *(GPUPackedNormal *)GPU_vertbuf_raw_step(tan_step) = *t2;
+    *(GPUPackedNormal *)GPU_vertbuf_raw_step(tan_step) = *t3;
+  }
 }
 
-void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(ListBase *lb,
-                                                         GPUVertBuf *vbo_pos_nor,
-                                                         GPUVertBuf *vbo_uv)
+void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv_and_tan(ListBase *lb,
+                                                                 GPUVertBuf *vbo_pos_nor,
+                                                                 GPUVertBuf *vbo_uv,
+                                                                 GPUVertBuf *vbo_tan)
 {
   static GPUVertFormat format_pos_nor = {0};
   static GPUVertFormat format_uv = {0};
+  static GPUVertFormat format_tan = {0};
   static struct {
-    uint pos, nor, uv;
+    uint pos, nor, uv, tan;
   } attr_id;
   if (format_pos_nor.attr_len == 0) {
     /* initialize vertex format */
@@ -404,9 +444,15 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(ListBase *lb,
         &format_pos_nor, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
     attr_id.nor = GPU_vertformat_attr_add(
         &format_pos_nor, "nor", GPU_COMP_I10, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
+
     /* UVs are in [0..1] range. We can compress them. */
     attr_id.uv = GPU_vertformat_attr_add(
         &format_uv, "u", GPU_COMP_I16, 2, GPU_FETCH_INT_TO_FLOAT_UNIT);
+    GPU_vertformat_alias_add(&format_uv, "au");
+
+    attr_id.tan = GPU_vertformat_attr_add(
+        &format_tan, "t", GPU_COMP_I10, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+    GPU_vertformat_alias_add(&format_tan, "at");
   }
 
   int vbo_len_capacity = curve_render_surface_tri_len_get(lb) * 3;
@@ -414,6 +460,7 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(ListBase *lb,
   GPUVertBufRaw pos_step = {0};
   GPUVertBufRaw nor_step = {0};
   GPUVertBufRaw uv_step = {0};
+  GPUVertBufRaw tan_step = {0};
 
   if (DRW_TEST_ASSIGN_VBO(vbo_pos_nor)) {
     GPU_vertbuf_init_with_format(vbo_pos_nor, &format_pos_nor);
@@ -426,6 +473,11 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(ListBase *lb,
     GPU_vertbuf_data_alloc(vbo_uv, vbo_len_capacity);
     GPU_vertbuf_attr_get_raw_data(vbo_uv, attr_id.uv, &uv_step);
   }
+  if (DRW_TEST_ASSIGN_VBO(vbo_tan)) {
+    GPU_vertbuf_init_with_format(vbo_tan, &format_tan);
+    GPU_vertbuf_data_alloc(vbo_tan, vbo_len_capacity);
+    GPU_vertbuf_attr_get_raw_data(vbo_tan, attr_id.tan, &tan_step);
+  }
 
   BKE_displist_normals_add(lb);
 
@@ -440,6 +492,16 @@ void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(ListBase *lb,
       if (dl->type == DL_INDEX3) {
         /* Currently 'DL_INDEX3' is always a flat surface with a single normal. */
         const GPUPackedNormal pnor = GPU_normal_convert_i10_v3(dl->nors);
+
+        GPUPackedNormal ptan = {0, 0, 0, 1};
+        if (tan_step.size != 0) {
+          float tan[3];
+          /* We consider the surface flat so the vector is already ort

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list