[Bf-blender-cvs] [4c291b1191d] lineart-shadow: LineArt: Lit/shade filtering logic corrected.

YimingWu noreply at git.blender.org
Fri Apr 8 16:12:27 CEST 2022


Commit: 4c291b1191d09d564f6a57f8f6f8bd0210ceafcb
Author: YimingWu
Date:   Fri Apr 8 22:08:31 2022 +0800
Branches: lineart-shadow
https://developer.blender.org/rB4c291b1191d09d564f6a57f8f6f8bd0210ceafcb

LineArt: Lit/shade filtering logic corrected.

Intersection lines won't work at the moment.

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

M	source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M	source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c

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

diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 463846fb9fc..b9e05e3639c 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -87,6 +87,9 @@ typedef struct LineartElementLinkNode {
   void *object_ref;
   eLineArtElementNodeFlag flags;
 
+  /* For edge element link nodes, used for shadow edge matching. */
+  int obindex;
+
   /** Per object value, always set, if not enabled by #ObjectLineArt, then it's set to global. */
   float crease_threshold;
 } LineartElementLinkNode;
@@ -100,6 +103,11 @@ typedef struct LineartEdgeSegment {
 
   /* Used to filter line art occlusion edges */
   unsigned char material_mask_bits;
+
+  /* Only used to mark "lit/shade" for now, But reserverd bits for material info.
+   * TODO(Yiming): Transfer material masks from shadow results
+   * onto here so then we can even filter transparent shadows. */
+  unsigned char shadow_mask_bits;
 } LineartEdgeSegment;
 
 typedef struct LineartShadowSegmentContainer {
@@ -305,6 +313,11 @@ typedef struct LineartRenderBuffer {
    * calculation is finished. */
   LineartStaticMemPool *shadow_data_pool;
 
+  /* Storing shadow edge eln, array, and cuts for shadow information, so it's avaliable when line
+   * art runs the second time for occlusion. Either a reference to LineartCache::shadow_data_pool
+   * (shadow stage) or a reference to LineartRenderBuffer::render_data_pool (final stage). */
+  LineartStaticMemPool *edge_data_pool;
+
   /*  Render status */
   double view_vector[3];
   double view_vector_secondary[3]; /* For shadow. */
@@ -417,8 +430,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_edges;
+
+  /** Shadow-computed feature lines from original meshes to be matched with the second load of
+   * meshes thus providing lit/shade info in the second run of line art. */
+  ListBase shadow_elns;
 
   /** Cache only contains edge types specified in this variable. */
   uint16_t rb_edge_types;
@@ -472,8 +487,8 @@ typedef struct LineartRenderTaskInfo {
 #define LRT_OBINDEX_SHIFT 20
 #define LRT_OBINDEX_LOWER 0x0fffff /* Lower 20 bits. */
 #define LRT_EDGE_IDENTIFIER(obi, e) \
-  ((((obi->obindex << LRT_OBINDEX_SHIFT) | (e->v1->index & LRT_OBINDEX_LOWER)) << 32) | \
-   ((obi->obindex << LRT_OBINDEX_SHIFT) | (e->v2->index & LRT_OBINDEX_LOWER)))
+  (((uint64_t)((obi->obindex << 0) | (e->v1->index & LRT_OBINDEX_LOWER)) << 32) | \
+   ((obi->obindex << 0) | (e->v2->index & LRT_OBINDEX_LOWER)))
 
 typedef struct LineartObjectInfo {
   struct LineartObjectInfo *next;
@@ -515,6 +530,7 @@ typedef struct LineartObjectLoadTaskInfo {
   LineartObjectInfo *pending;
   /* Used to spread the load across several threads. This can not overflow. */
   uint64_t total_faces;
+  ListBase *shadow_elns;
 } LineartObjectLoadTaskInfo;
 
 /**
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index cf11c1dea1a..821e137985e 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -162,7 +162,7 @@ static LineartEdgeSegment *lineart_give_segment(LineartRenderBuffer *rb)
   BLI_spin_unlock(&rb->lock_cuts);
 
   /* Otherwise allocate some new memory. */
-  return (LineartEdgeSegment *)lineart_mem_acquire_thread(&rb->render_data_pool,
+  return (LineartEdgeSegment *)lineart_mem_acquire_thread(rb->edge_data_pool,
                                                           sizeof(LineartEdgeSegment));
 }
 
@@ -174,7 +174,8 @@ static void lineart_edge_cut(LineartRenderBuffer *rb,
                              double start,
                              double end,
                              uchar material_mask_bits,
-                             uchar mat_occlusion)
+                             uchar mat_occlusion,
+                             uchar shadow_bits)
 {
   LineartEdgeSegment *es, *ies, *next_es, *prev_es;
   LineartEdgeSegment *cut_start_before = 0, *cut_end_before = 0;
@@ -311,6 +312,8 @@ static void lineart_edge_cut(LineartRenderBuffer *rb,
   for (es = ns; es && es != ns2; es = es->next) {
     es->occlusion += mat_occlusion;
     es->material_mask_bits |= material_mask_bits;
+    /* Currently only register lit/shade, see LineartEdgeSegment::shadow_mask_bits for details. */
+    es->shadow_mask_bits |= shadow_bits;
   }
 
   /* Reduce adjacent cutting points of the same level, which saves memory. */
@@ -432,7 +435,7 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
                                                       rb->shift_y,
                                                       &l,
                                                       &r)) {
-        lineart_edge_cut(rb, e, l, r, tri->base.material_mask_bits, tri->base.mat_occlusion);
+        lineart_edge_cut(rb, e, l, r, tri->base.material_mask_bits, tri->base.mat_occlusion, 0);
         if (e->min_occ > rb->max_occlusion_level) {
           /* No need to calculate any longer on this line because no level more than set value is
            * going to show up in the rendered result. */
@@ -733,12 +736,10 @@ static LineartElementLinkNode *lineart_memory_get_edge_space(LineartRenderBuffer
 {
   LineartElementLinkNode *eln;
 
-  LineartEdge *render_edges = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartEdge) * 64);
+  LineartEdge *render_edges = lineart_mem_acquire(rb->edge_data_pool, sizeof(LineartEdge) * 64);
 
-  eln = lineart_list_append_pointer_pool_sized(&rb->line_buffer_pointers,
-                                               &rb->render_data_pool,
-                                               render_edges,
-                                               sizeof(LineartElementLinkNode));
+  eln = lineart_list_append_pointer_pool_sized(
+      &rb->line_buffer_pointers, rb->edge_data_pool, render_edges, sizeof(LineartElementLinkNode));
   eln->element_count = 64;
   eln->crease_threshold = rb->crease_threshold;
   eln->flags |= LRT_ELEMENT_IS_ADDITIONAL;
@@ -1475,12 +1476,21 @@ static void lineart_mvert_transform_task(void *__restrict userdata,
   v->index = i;
 }
 
-static int lineart_edge_type_duplication_count(char eflag)
+static const int LRT_MESH_EDGE_TYPES[] = {
+    LRT_EDGE_FLAG_EDGE_MARK,
+    LRT_EDGE_FLAG_CONTOUR,
+    LRT_EDGE_FLAG_CREASE,
+    LRT_EDGE_FLAG_MATERIAL,
+    LRT_EDGE_FLAG_LOOSE,
+    LRT_EDGE_FLAG_CONTOUR_SECONDARY,
+};
+
+static int lineart_edge_type_duplication_count(int eflag)
 {
   int count = 0;
   /* See eLineartEdgeFlag for details. */
   for (int i = 0; i < 6; i++) {
-    if (eflag & (1 << i)) {
+    if (eflag & LRT_MESH_EDGE_TYPES[i]) {
       count++;
     }
   }
@@ -1618,6 +1628,7 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
     }
 
     if (rb->use_contour_secondary) {
+      view_vector = vv;
       if (rb->cam_is_persp_secondary) {
         sub_v3_v3v3_db(view_vector, vert->gloc, rb->camera_pos_secondary);
       }
@@ -1629,9 +1640,7 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
       dot_2 = dot_v3v3_db(view_vector, tri2->gn);
 
       if ((result = dot_1 * dot_2) <= 0 && (dot_1 + dot_2)) {
-        /* Note: we only allow one contour type for now, either it's from light camera or it's from
-         * viewing camera, hence directly assign. */
-        edge_flag_result = LRT_EDGE_FLAG_CONTOUR_SECONDARY;
+        edge_flag_result |= LRT_EDGE_FLAG_CONTOUR_SECONDARY;
       }
     }
 
@@ -2112,8 +2121,49 @@ static void lineart_load_tri_reduce(const void *__restrict UNUSED(userdata),
   BLI_edgehash_free(data_reduce->edge_hash, NULL);
 }
 
+static LineartElementLinkNode *lineart_find_matching_eln(ListBase *shadow_elns, int obindex)
+{
+  LISTBASE_FOREACH (LineartElementLinkNode *, eln, shadow_elns) {
+    if (eln->obindex == obindex) {
+      return eln;
+    }
+  }
+  return NULL;
+}
+
+static LineartEdge *lineart_find_matching_edge(LineartElementLinkNode *shadow_eln,
+                                               uint64_t edge_identifier)
+{
+  LineartEdge *elist = (LineartEdge *)shadow_eln->pointer;
+  for (int i = 0; i < shadow_eln->element_count; i++) {
+    if (elist[i].from_shadow == (LineartEdge *)edge_identifier) {
+      return &elist[i];
+    }
+  }
+  return NULL;
+}
+
+static void lineart_register_shadow_cuts(LineartRenderBuffer *rb,
+                                         LineartEdge *e,
+                                         LineartEdge *shadow_edge)
+{
+  LISTBASE_FOREACH (LineartEdgeSegment *, es, &shadow_edge->segments) {
+    if (es->occlusion != 0) {
+      /* Convert to view space cutting points. */
+      double la1 = es->at;
+      double la2 = es->next ? es->next->at : 1.0f;
+      la1 = la1 * e->v2->fbcoord[3] /
+            (e->v1->fbcoord[3] - la1 * (e->v1->fbcoord[3] - e->v2->fbcoord[3]));
+      la2 = la2 * e->v2->fbcoord[3] /
+            (e->v1->fbcoord[3] - la2 * (e->v1->fbcoord[3] - e->v2->fbcoord[3]));
+      lineart_edge_cut(rb, e, la1, la2, 0, 10, es->occlusion != 0);
+    }
+  }
+}
+
 static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
-                                                  LineartRenderBuffer *re_buf)
+                                                  LineartRenderBuffer *re_buf,
+                                                  ListBase *shadow_elns)
 {
   LineartElementLinkNode *elem_link_node;
   LineartVert *la_v_arr;
@@ -2392,18 +2442,24 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info,
     BLI_edgehash_free(edge_hash, NULL);
   }
 
-  la_edge_arr = lineart_mem_acquire_thread(&re_buf->render_data_pool,
+  la_edge_arr = lineart_mem_acquire_thread(re_buf->edge_data_pool,
                                            sizeof(LineartEdge) * allocate_la_e);
-  la_seg_arr = lineart_mem_acquire_thread(&

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list