[Bf-blender-cvs] [795e46c20e4] lineart-shadow: LineArt: obindex lookup for matching shadow edges.

YimingWu noreply at git.blender.org
Fri Jul 30 09:41:15 CEST 2021


Commit: 795e46c20e4ac03891ac28a75cd4468377f9cbd9
Author: YimingWu
Date:   Fri Jul 30 15:41:04 2021 +0800
Branches: lineart-shadow
https://developer.blender.org/rB795e46c20e4ac03891ac28a75cd4468377f9cbd9

LineArt: obindex lookup for matching shadow edges.

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

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 4f5b11d1bea..75f7d7b6cfa 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -57,6 +57,10 @@ typedef struct LineartTriangle {
   unsigned char mat_occlusion;
   unsigned char flags; /* #eLineartTriangleFlags */
 
+  /* target_reference = (obi->obindex | triangle_index) */
+  /*        higher 12 bits-------^         ^-----index in object, lower 20 bits */
+  int target_reference;
+
   /**
    * Only use single link list, because we don't need to go back in order.
    * This variable is also reused to store the pointer to adjacent lines of this triangle before
@@ -131,6 +135,7 @@ typedef struct LineartShadowSegment {
   double fbc1[4], fbc2[4];
   /* Global position. */
   double g1[4], g2[4];
+  int target_reference;
 } LineartShadowSegment;
 
 typedef struct LineartVert {
@@ -178,6 +183,8 @@ typedef struct LineartEdge {
   uint16_t flags;
   uint8_t intersection_mask;
 
+  int target_reference;
+
   /**
    * Still need this entry because culled lines will not add to object
    * #LineartElementLinkNode node (known as `eln` internally).
@@ -440,6 +447,9 @@ typedef struct LineartRenderTaskInfo {
 
 } LineartRenderTaskInfo;
 
+#define LRT_OBINDEX_SHIFT 20
+#define LRT_OBINDEX_LOWER 0x0fffff /* Lower 20 bits. */
+
 typedef struct LineartObjectInfo {
   struct LineartObjectInfo *next;
   struct Object *original_ob;
@@ -452,6 +462,9 @@ typedef struct LineartObjectInfo {
   uint8_t override_intersection_mask;
   int global_i_offset;
 
+  /* Shifted LRT_OBINDEX_SHIFT bits to be combined with object triangle index. */
+  int obindex;
+
   bool free_use_mesh;
 
   /* Threads will add lines inside here, when all threads are done, we combine those into the
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index e55fb6f6ffb..b07165a25eb 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -1937,6 +1937,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu
 
     tri->intersection_mask = obi->override_intersection_mask;
 
+    tri->target_reference = (obi->obindex | (i & LRT_OBINDEX_LOWER));
+
     double gn[3];
     copy_v3db_v3fl(gn, f->no);
     mul_v3_mat3_m4v3_db(tri->gn, normal, gn);
@@ -2235,6 +2237,7 @@ static void lineart_main_load_geometries(
 
   int thread_count = rb->thread_count;
   int bound_box_discard_count = 0;
+  int obindex = 0;
 
   /* This memory is in render buffer memory pool. So we don't need to free those after loading.
    */
@@ -2242,6 +2245,10 @@ static void lineart_main_load_geometries(
       &rb->render_data_pool, sizeof(LineartObjectLoadTaskInfo) * thread_count);
 
   DEG_OBJECT_ITER_BEGIN (depsgraph, ob, flags) {
+    /* Do the increment even for discarded objects, so that in different culling conditions we can
+     * get the same reference to the same object. */
+    obindex++;
+
     LineartObjectInfo *obi = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartObjectInfo));
     obi->usage = lineart_usage_check(scene->master_collection, ob);
     obi->override_intersection_mask = lineart_intersection_mask_check(scene->master_collection,
@@ -2253,6 +2260,8 @@ static void lineart_main_load_geometries(
       continue;
     }
 
+    obi->obindex = obindex << LRT_OBINDEX_SHIFT;
+
     /* Prepare the matrix used for transforming this specific object (instance). This has to be
      * done before mesh boundbox check because the function needs that. */
     mul_m4db_m4db_m4fl_uniq(obi->model_view_proj, rb->view_projection, ob->obmat);
@@ -2494,16 +2503,18 @@ static bool lineart_triangle_edge_image_space_occlusion(SpinLock *UNUSED(spl),
   dot_r = dot_v3v3_db(Rv, tri->gn);
   dot_f = dot_v3v3_db(Cv, tri->gn);
 
-  if ((e->flags & LRT_EDGE_FLAG_PROJECTED_SHADOW) && LRT_SHADOW_CLOSE_ENOUGH(dot_l, 0) &&
-      LRT_SHADOW_CLOSE_ENOUGH(dot_r, 0)) {
+  if ((e->flags & LRT_EDGE_FLAG_PROJECTED_SHADOW) &&
+      (e->target_reference == tri->target_reference || !e->target_reference) &&
+      LRT_SHADOW_CLOSE_ENOUGH(dot_l, 0) && LRT_SHADOW_CLOSE_ENOUGH(dot_r, 0)) {
     /* Currently unable to precisely determine if the edge is really from this triangle. */
-    /*if ((dot_f > 0 && (e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT)) ||
-        (dot_f < 0 && (!(e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT)))) {
+    if (e->target_reference &&
+        (((dot_f > 0) && (e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT)) ||
+         ((dot_f < 0) && (!(e->flags & LRT_EDGE_FLAG_SHADOW_FACING_LIGHT))))) {
       *from = 0.0f;
       *to = 1.0f;
       return true;
     }
-    */
+
     return false;
   }
 
@@ -3212,7 +3223,7 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene,
   rb->max_occlusion_level = lmd->level_end_override;
 
   rb->use_back_face_culling = (lmd->calculation_flags & LRT_USE_BACK_FACE_CULLING) != 0;
-  if (rb->max_occlusion_level < 1) {
+  if (rb->max_occlusion_level < 1 && !rb->use_shadow) {
     rb->use_back_face_culling = true;
     if (G.debug_value == 4000) {
       printf("Backface culling enabled automatically.\n");
@@ -4402,7 +4413,8 @@ static bool lineart_do_closest_segment(bool is_persp,
                                        double *r_new_in_the_middle,
                                        double *r_new_in_the_middle_global,
                                        double *r_new_at,
-                                       bool *is_side_2r)
+                                       bool *is_side_2r,
+                                       bool *use_new_ref)
 {
   int side = 0;
   int zid = is_persp ? 3 : 2;
@@ -4434,9 +4446,11 @@ static bool lineart_do_closest_segment(bool is_persp,
   if (side) {
     if (side > 0) {
       *is_side_2r = true;
+      *use_new_ref = true;
     }
     else if (side < 0) {
       *is_side_2r = false;
+      *use_new_ref = false;
     }
     return false;
   }
@@ -4450,6 +4464,7 @@ static bool lineart_do_closest_segment(bool is_persp,
   interp_v3_v3v3_db(r_new_in_the_middle, s2fbl, s2fbr, *r_new_at);
   r_new_in_the_middle[3] = interpd(s2fbr[3], s2fbl[3], ga);
   interp_v3_v3v3_db(r_new_in_the_middle_global, s1gl, s1gr, ga);
+  *use_new_ref = true;
 
   return true;
 }
@@ -4535,7 +4550,8 @@ static void lineart_shadow_edge_cut(LineartRenderBuffer *rb,
                                     double *end_gpos,
                                     double *start_fbc,
                                     double *end_fbc,
-                                    bool facing_light)
+                                    bool facing_light,
+                                    int target_reference)
 {
   LineartShadowSegment *es, *ies;
   LineartShadowSegment *cut_start_after = e->shadow_segments.first,
@@ -4636,7 +4652,7 @@ static void lineart_shadow_edge_cut(LineartRenderBuffer *rb,
 
   double *s1fbl, *s1fbr, *s1gl, *s1gr;
   double tg1[3], tg2[3], tfbc1[4], tfbc2[4], mg1[3], mfbc1[4], mg2[3], mfbc2[4];
-  bool is_side_2r, has_middle = false;
+  bool is_side_2r, has_middle = false, use_new_ref;
   copy_v4_v4_db(tfbc1, start_fbc);
   copy_v3_v3_db(tg1, start_gpos);
 
@@ -4670,6 +4686,7 @@ static void lineart_shadow_edge_cut(LineartRenderBuffer *rb,
         copy_v3_v3_db(ns2->g2, mg2);
         /* Need to restore the flag for next segment's reference. */
         sr->flag = es->flag;
+        sr->target_reference = es->target_reference;
       }
     }
 
@@ -4692,12 +4709,14 @@ static void lineart_shadow_edge_cut(LineartRenderBuffer *rb,
                                                  r_new_in_the_middle,
                                                  r_new_in_the_middle_global,
                                                  &r_new_at,
-                                                 &is_side_2r))) {
+                                                 &is_side_2r,
+                                                 &use_new_ref))) {
       LineartShadowSegment *ss_middle = lineart_give_shadow_segment(rb);
       ss_middle->at = interpf(sr->at, sl->at, r_new_at);
       ss_middle->flag = is_side_2r ?
                             (LRT_SHADOW_CASTED | (facing_light ? LRT_SHADOW_FACING_LIGHT : 0)) :
                             LRT_SHADOW_CASTED;
+      ss_middle->target_reference = (is_side_2r ? (target_reference) : sl->target_reference);
       copy_v3_v3_db(ss_middle->g1, r_new_in_the_middle_global);
       copy_v3_v3_db(ss_middle->g2, r_new_in_the_middle_global);
       copy_v4_v4_db(ss_middle->fbc1, r_new_in_the_middle);
@@ -4713,10 +4732,12 @@ static void lineart_shadow_edge_cut(LineartRenderBuffer *rb,
     if (has_middle) {
       sl->flag = LRT_SHADOW_CASTED |
                  (is_side_2r ? 0 : (facing_light ? LRT_SHADOW_FACING_LIGHT : 0));
+      sl->target_reference = is_side_2r ? es->target_reference : target_reference;
     }
     else {
       sl->flag = LRT_SHADOW_CASTED |
                  (is_side_2r ? (facing_light ? LRT_SHADOW_FACING_LIGHT : 0) : 0);
+      sl->target_reference = (use_new_ref ? target_reference : es->target_reference);
     }
 
     copy_v4_v4_db(tfbc1, tfbc2);
@@ -4917,8 +4938,16 @@ static void lineart_shadow_cast(LineartRenderBuffer *rb)
                                               global_l,
                                               global_r,
                                               &facing_light)) {
-          lineart_shadow_edge_cut(
-              rb, ssc, at_l, at_r, global_l, global_r, fb_l, fb_r, facing_light);
+          lineart_shadow_edge_cut(rb,
+                                  ssc,
+                                  at_l,
+                                  at_r,
+                                  global_l,
+                                  global_r,
+                                  fb_l,
+                                  fb_r,
+                                  facing_light,
+                                  tri->base.target_reference);
         }
       }
       LRT

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list