[Bf-blender-cvs] [eb63554e3b4] lineart-shadow: LineArt: Able to run shadow.

YimingWu noreply at git.blender.org
Tue Jul 13 10:45:58 CEST 2021


Commit: eb63554e3b4bee1b86c5f64173e7135af447febd
Author: YimingWu
Date:   Tue Jul 13 16:30:01 2021 +0800
Branches: lineart-shadow
https://developer.blender.org/rBeb63554e3b4bee1b86c5f64173e7135af447febd

LineArt: Able to run shadow.

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

M	source/blender/blenlib/BLI_math_vector.h
M	source/blender/blenlib/intern/math_vector_inline.c
M	source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
M	source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M	source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
M	source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h

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

diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 2f4cf1721af..3ce4b2d36dd 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -56,6 +56,10 @@ MINLINE void swap_v2_v2(float a[2], float b[2]);
 MINLINE void swap_v3_v3(float a[3], float b[3]);
 MINLINE void swap_v4_v4(float a[4], float b[4]);
 
+MINLINE void swap_v2_v2_db(double a[2], double b[2]);
+MINLINE void swap_v3_v3_db(double a[3], double b[3]);
+MINLINE void swap_v4_v4_db(double a[4], double b[4]);
+
 /* unsigned char */
 MINLINE void copy_v2_v2_uchar(unsigned char r[2], const unsigned char a[2]);
 MINLINE void copy_v3_v3_uchar(unsigned char r[3], const unsigned char a[3]);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index db9ece81c59..bb19d24a2f9 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -330,6 +330,27 @@ MINLINE void swap_v4_v4(float a[4], float b[4])
   SWAP(float, a[3], b[3]);
 }
 
+MINLINE void swap_v2_v2_db(double a[2], double b[2])
+{
+  SWAP(double, a[0], b[0]);
+  SWAP(double, a[1], b[1]);
+}
+
+MINLINE void swap_v3_v3_db(double a[3], double b[3])
+{
+  SWAP(double, a[0], b[0]);
+  SWAP(double, a[1], b[1]);
+  SWAP(double, a[2], b[2]);
+}
+
+MINLINE void swap_v4_v4_db(double a[4], double b[4])
+{
+  SWAP(double, a[0], b[0]);
+  SWAP(double, a[1], b[1]);
+  SWAP(double, a[2], b[2]);
+  SWAP(double, a[3], b[3]);
+}
+
 /* float args -> vec */
 MINLINE void copy_v2_fl2(float v[2], float x, float y)
 {
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index 87a221b3bf7..9ff15912752 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -390,7 +390,7 @@ static void edge_types_panel_draw(const bContext *UNUSED(C), Panel *panel)
     uiItemR(entry, ptr, "light_contour_object", 0, "", ICON_NONE);
   }
 
-  uiItemR(col, ptr, "use_shadow", 0, "", ICON_NONE);
+  uiItemR(col, ptr, "use_shadow", 0, IFACE_("Casted Shadow"), ICON_NONE);
 
   uiItemR(layout, ptr, "use_overlap_edge_type_support", 0, IFACE_("Allow Overlap"), ICON_NONE);
 }
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 3bc8f6d14a0..53ae03589e2 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -106,14 +106,22 @@ typedef struct LineartEdgeSegment {
   unsigned char material_mask_bits;
 } LineartEdgeSegment;
 
-typedef struct LineartShadowEdge {
-  /* Two end points in framebuffer coordinates viiewed from the light source. */
+typedef struct LineartShadowSegmentContainer {
+  struct LineartShadowSegmentContainer *next, *prev;
+  /* Two end points in framebuffer coordinates viewed from the light source. */
   double fbc1[4], fbc2[4];
+  struct LineartEdge *e_ref;
   ListBase shadow_segments;
 } LineartShadowSegmentContainer;
 
+enum eLineartShadowSegmentFlag {
+  LRT_SHADOW_CASTED = 1,
+};
+
 typedef struct LineartShadowSegment {
-  struct LineartShadowSegment *prev, *next;
+  struct LineartShadowSegment *next, *prev;
+  /* eLineartShadowSegmentFlag */
+  int flag;
   /* In NDC, not in global linear. */
   double at;
   /* Left and right pos, because when casting shadows at some point there will be
@@ -283,6 +291,10 @@ typedef struct LineartRenderBuffer {
    * completes which serves as a cache. */
   LineartStaticMemPool *chain_data_pool;
 
+  /* Reference to LineartCache::shadow_data_pool, stay available until the final round of line art
+   * calculation is finished. */
+  LineartStaticMemPool *shadow_data_pool;
+
   /*  Render status */
   double view_vector[3];
 
@@ -298,10 +310,12 @@ typedef struct LineartRenderBuffer {
   ListBase edge_mark;
   ListBase floating;
   ListBase light_contour;
+  ListBase shadow;
 
   ListBase chains;
 
-  ListBase shadow_segments;
+  /* Intermediate shadow results, list of LineartShadowSegmentContainer */
+  ListBase shadow_containers;
 
   /* For managing calculation tasks for multiple threads. */
   SpinLock lock_task;
@@ -378,10 +392,10 @@ typedef struct LineartCache {
   /** A copy of rb->Chains after calculation is done, then we can destroy rb. */
   ListBase chains;
   /** Shadow segments to be included into occlusion calculation in the second run of line art. */
-  ListBase shadow_segments;
+  ListBase shadow_edges;
 
   /** Cache only contains edge types specified in this variable. */
-  unsigned char rb_edge_types;
+  uint16_t rb_edge_types;
 } LineartCache;
 
 #define DBL_TRIANGLE_LIM 1e-8
@@ -419,6 +433,7 @@ typedef struct LineartRenderTaskInfo {
   ListBase edge_mark;
   ListBase floating;
   ListBase light_contour;
+  ListBase shadow;
 
 } LineartRenderTaskInfo;
 
@@ -445,6 +460,7 @@ typedef struct LineartObjectInfo {
   ListBase edge_mark;
   ListBase floating;
   ListBase light_contour;
+  ListBase shadow;
 
 } LineartObjectInfo;
 
@@ -628,6 +644,90 @@ BLI_INLINE int lineart_LineIntersectTest2d(
 #endif
 }
 
+BLI_INLINE int lineart_line_isec_2d_ignore_line2pos(
+    const double *a1, const double *a2, const double *b1, const double *b2, double *aRatio)
+{
+#define USE_VECTOR_LINE_INTERSECTION
+#ifdef USE_VECTOR_LINE_INTERSECTION
+
+  /* from isect_line_line_v2_point() */
+
+  double s10[2], s32[2];
+  double div;
+
+  sub_v2_v2v2_db(s10, a2, a1);
+  sub_v2_v2v2_db(s32, b2, b1);
+
+  div = cross_v2v2_db(s10, s32);
+  if (div != 0.0f) {
+    const double u = cross_v2v2_db(a2, a1);
+    const double v = cross_v2v2_db(b2, b1);
+
+    const double rx = ((s32[0] * u) - (s10[0] * v)) / div;
+    const double ry = ((s32[1] * u) - (s10[1] * v)) / div;
+
+    if (fabs(a2[0] - a1[0]) > fabs(a2[1] - a1[1])) {
+      *aRatio = ratiod(a1[0], a2[0], rx);
+      if ((*aRatio) > 0 && (*aRatio) < 1) {
+        return 1;
+      }
+      return 0;
+    }
+
+    *aRatio = ratiod(a1[1], a2[1], ry);
+    if ((*aRatio) > 0 && (*aRatio) < 1) {
+      return 1;
+    }
+    return 0;
+  }
+  return 0;
+
+#else
+  double k1, k2;
+  double x;
+  double y;
+  double ratio;
+  double x_diff = (a2[0] - a1[0]);
+  double x_diff2 = (b2[0] - b1[0]);
+
+  if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff, 0)) {
+    if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff2, 0)) {
+      *aRatio = 0;
+      return 0;
+    }
+    double r2 = ratiod(b1[0], b2[0], a1[0]);
+    x = interpd(b2[0], b1[0], r2);
+    y = interpd(b2[1], b1[1], r2);
+    *aRatio = ratio = ratiod(a1[1], a2[1], y);
+  }
+  else {
+    if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff2, 0)) {
+      ratio = ratiod(a1[0], a2[0], b1[0]);
+      x = interpd(a2[0], a1[0], ratio);
+      *aRatio = ratio;
+    }
+    else {
+      k1 = (a2[1] - a1[1]) / x_diff;
+      k2 = (b2[1] - b1[1]) / x_diff2;
+
+      if ((k1 == k2))
+        return 0;
+
+      x = (a1[1] - b1[1] - k1 * a1[0] + k2 * b1[0]) / (k2 - k1);
+
+      ratio = (x - a1[0]) / x_diff;
+
+      *aRatio = ratio;
+    }
+  }
+
+  if (ratio <= 0 || ratio > 1)
+    return 0;
+
+  return 1;
+#endif
+}
+
 struct Depsgraph;
 struct Scene;
 struct LineartRenderBuffer;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 5484142f12c..8d56e4ad898 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -475,6 +475,7 @@ static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRend
   LRT_ASSIGN_OCCLUSION_TASK(edge_mark);
   LRT_ASSIGN_OCCLUSION_TASK(floating);
   LRT_ASSIGN_OCCLUSION_TASK(light_contour);
+  LRT_ASSIGN_OCCLUSION_TASK(shadow);
 
 #undef LRT_ASSIGN_OCCLUSION_TASK
 
@@ -517,6 +518,10 @@ static void lineart_occlusion_worker(TaskPool *__restrict UNUSED(pool), LineartR
     for (eip = rti->light_contour.first; eip && eip != rti->light_contour.last; eip = eip->next) {
       lineart_occlusion_single_line(rb, eip, rti->thread_id);
     }
+
+    for (eip = rti->shadow.first; eip && eip != rti->shadow.last; eip = eip->next) {
+      lineart_occlusion_single_line(rb, eip, rti->thread_id);
+    }
   }
 }
 
@@ -541,6 +546,7 @@ static void lineart_main_occlusion_begin(LineartRenderBuffer *rb)
   rb->edge_mark.last = rb->edge_mark.first;
   rb->floating.last = rb->floating.first;
   rb->light_contour.last = rb->light_contour.first;
+  rb->shadow.last = rb->shadow.first;
 
   TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH);
 
@@ -1683,6 +1689,9 @@ static void lineart_add_edge_to_list(LineartRenderBuffer *rb, LineartEdge *e)
     case LRT_EDGE_FLAG_LIGHT_CONTOUR:
       lineart_prepend_edge_direct(&rb->light_contour.first, e);
       break;
+    case LRT_EDGE_FLAG_PROJECTED_SHADOW:
+      lineart_prepend_edge_direct(&rb->shadow.first, e);
+      break;
   }
 }
 
@@ -1716,6 +1725,9 @@ static void lineart_add_edge_to_list_thread(LineartObjectInfo *obi, LineartEdge
     case LRT_EDGE_FLAG_LIGHT_CONTOUR:
       LRT_ASSIGN_EDGE(light_contour);
       break;
+    case LRT_EDGE_FLAG_PROJECTED_SHADOW:
+      LRT_ASSIGN_EDGE(shadow);
+      break;
   }
 #undef LRT_ASSIGN_EDGE
 }
@@ -3012,6 +3024,7 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb)
   memset(&rb->material, 0, sizeof(ListBase));
   memset(&rb->floating, 0, sizeof(ListBase));
   memset(&rb->light_contour, 0, sizeof(ListBase));
+  memset(&rb->shadow, 0, sizeof(ListBase));
 
   BLI_listbase_clear(&rb->chains);
   BLI_listbase_clear(&rb->wasted_cuts);
@@ -3024,6 +3037,8 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb)
   BLI_spin_end(&rb->lock_cuts);
   BLI_spin_end(&rb->render_data_pool.lock_mem);
 
+  MEM_freeN((void *)rb->lock_bounding_areas);
+
   for (int i = 0; i < rb->thread_count; i++) {
     BLI_spin_end(&rb->lock_bounding_areas[i]);
   }
@@ -3031,6 +3046,31 @@ static void lineart_destroy_render_data(LineartRenderBuffer *rb)
   lineart_mem_destroy(&rb->render_data_pool);
 }
 
+static void lineart_destroy_render_data_keep_init(Linear

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list