[Bf-blender-cvs] [1e8bd566f68] lineart-shadow: LineArt: WIP shadow thing...

YimingWu noreply at git.blender.org
Fri Jul 9 09:34:15 CEST 2021


Commit: 1e8bd566f6896bd90e977f2d4c317b28b672a15f
Author: YimingWu
Date:   Fri Jul 9 15:32:18 2021 +0800
Branches: lineart-shadow
https://developer.blender.org/rB1e8bd566f6896bd90e977f2d4c317b28b672a15f

LineArt: WIP shadow thing...

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

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/makesdna/DNA_gpencil_modifier_defaults.h
M	source/blender/makesdna/DNA_gpencil_modifier_types.h
M	source/blender/makesdna/DNA_lineart_types.h
M	source/blender/makesrna/intern/rna_gpencil_modifier.c

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

diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index e4c256e407b..f42c1302522 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -374,7 +374,9 @@ static void edge_types_panel_draw(const bContext *UNUSED(C), Panel *panel)
   sub = uiLayoutRowWithHeading(col, false, IFACE_("Light Contour"));
   uiItemR(sub, ptr, "use_light_contour", 0, "", ICON_NONE);
   entry = uiLayoutRow(sub, false);
-  uiLayoutSetActive(entry, (RNA_boolean_get(ptr, "use_light_contour")) || is_first);
+  uiLayoutSetActive(entry,
+                    (RNA_boolean_get(ptr, "use_light_contour")) ||
+                        (RNA_boolean_get(ptr, "use_light_contour")) || is_first);
   if (use_cache && !is_first) {
     uiItemL(entry, IFACE_("Reference Cached"), ICON_INFO);
   }
@@ -382,9 +384,38 @@ 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(layout, ptr, "use_overlap_edge_type_support", 0, IFACE_("Allow Overlap"), ICON_NONE);
 }
 
+static void options_shadow_camera_draw(const bContext *UNUSED(C), Panel *panel)
+{
+  uiLayout *layout = panel->layout;
+  PointerRNA ob_ptr;
+  PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, &ob_ptr);
+
+  const bool is_baked = RNA_boolean_get(ptr, "is_baked");
+  const bool use_cache = RNA_boolean_get(ptr, "use_cache");
+  const bool use_shadow = RNA_boolean_get(ptr, "use_shadow");
+  const bool is_first = BKE_gpencil_is_first_lineart_in_stack(ob_ptr.data, ptr->data);
+
+  uiLayoutSetPropSep(layout, true);
+  uiLayoutSetEnabled(layout, !is_baked);
+  uiLayoutSetActive(layout, use_shadow);
+
+  if (use_cache && !is_first) {
+    uiItemL(layout, "Cached from the first line art modifier.", ICON_INFO);
+    return;
+  }
+
+  uiItemR(layout, ptr, "shadow_camera_size", 0, NULL, ICON_NONE);
+
+  uiLayout *col = uiLayoutColumn(layout, true);
+  uiItemR(col, ptr, "shadow_camera_near", 0, NULL, ICON_NONE);
+  uiItemR(col, ptr, "shadow_camera_far", 0, NULL, ICON_NONE);
+}
+
 static void options_panel_draw(const bContext *UNUSED(C), Panel *panel)
 {
   uiLayout *layout = panel->layout;
@@ -743,6 +774,8 @@ static void panelRegister(ARegionType *region_type)
 
   gpencil_modifier_subpanel_register(
       region_type, "edge_types", "Edge Types", NULL, edge_types_panel_draw, panel_type);
+  gpencil_modifier_subpanel_register(
+      region_type, "shadow_camera", "Shadow Camera", NULL, options_shadow_camera_draw, panel_type);
   gpencil_modifier_subpanel_register(
       region_type, "geometry", "Geometry Processing", NULL, options_panel_draw, panel_type);
   gpencil_modifier_subpanel_register(
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 8e241c500d0..a92382aee0d 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -106,6 +106,13 @@ typedef struct LineartEdgeSegment {
   unsigned char material_mask_bits;
 } LineartEdgeSegment;
 
+typedef struct LineartShadowSegment {
+  LineartEdgeSegment base;
+  /* global left and right pos, because when casting shadows at some point there will be
+   * non-continuous cuts. */
+  double gl[4], gr[4];
+} LineartShadowSegment;
+
 typedef struct LineartVert {
   double gloc[3];
   double fbcoord[4];
@@ -216,6 +223,11 @@ enum eLineArtTileRecursiveLimit {
 #define LRT_TILE_SPLITTING_TRIANGLE_LIMIT 100
 #define LRT_TILE_EDGE_COUNT_INITIAL 32
 
+enum eLineartShadowCameraType {
+  LRT_SHADOW_CAMERA_DIRECTIONAL = 1,
+  LRT_SHADOW_CAMERA_POINT = 2,
+};
+
 typedef struct LineartRenderBuffer {
   struct LineartRenderBuffer *prev, *next;
 
@@ -228,6 +240,8 @@ typedef struct LineartRenderBuffer {
   double view_projection[4][4];
   double view[4][4];
 
+  bool do_shadow_cast;
+
   float overscan;
 
   struct LineartBoundingArea *initial_bounding_areas;
@@ -252,6 +266,7 @@ typedef struct LineartRenderBuffer {
   /** Use the one comes with Line Art. */
   LineartStaticMemPool render_data_pool;
   ListBase wasted_cuts;
+  ListBase wasted_shadow_cuts;
   SpinLock lock_cuts;
 
   /* This is just a reference to LineartCache::chain_data_pool, which is not cleared after line art
@@ -295,6 +310,7 @@ typedef struct LineartRenderBuffer {
   bool use_intersections;
   bool use_loose;
   bool use_light_contour;
+  bool use_shadow;
   bool fuzzy_intersections;
   bool fuzzy_everything;
   bool allow_boundaries;
@@ -321,6 +337,7 @@ typedef struct LineartRenderBuffer {
   double active_camera_pos[3]; /* Stroke offset calculation may use active or selected camera. */
   double near_clip, far_clip;
   float shift_x, shift_y;
+
   float crease_threshold;
   float chaining_image_threshold;
   float angle_splitting_threshold;
@@ -341,12 +358,15 @@ typedef struct LineartRenderBuffer {
 } LineartRenderBuffer;
 
 typedef struct LineartCache {
-  /** Separate memory pool for chain data, this goes to the cache, so when we free the main pool,
-   * chains will still be available. */
+  /** Separate memory pool for chain data and shadow, this goes to the cache, so when we free the
+   * main pool, chains and shadows will still be available. */
   LineartStaticMemPool chain_data_pool;
+  LineartStaticMemPool shadow_data_pool;
 
   /** 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;
 
   /** Cache only contains edge types specified in this variable. */
   unsigned char rb_edge_types;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 64a2096328a..078acdfad3e 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -385,26 +385,33 @@ static void lineart_bounding_area_line_add(LineartRenderBuffer *rb,
   ba->line_count++;
 }
 
+#define LRT_EDGE_BA_MARCHING_BEGIN \
+  double x = e->v1->fbcoord[0], y = e->v1->fbcoord[1]; \
+  LineartBoundingArea *ba = lineart_edge_first_bounding_area(rb, e); \
+  LineartBoundingArea *nba = ba; \
+  LineartTriangleThread *tri; \
+  /* These values are used for marching along the line. */ \
+  double l, r; \
+  double k = (e->v2->fbcoord[1] - e->v1->fbcoord[1]) / \
+             (e->v2->fbcoord[0] - e->v1->fbcoord[0] + 1e-30); \
+  int positive_x = (e->v2->fbcoord[0] - e->v1->fbcoord[0]) > 0 ? \
+                       1 : \
+                       (e->v2->fbcoord[0] == e->v1->fbcoord[0] ? 0 : -1); \
+  int positive_y = (e->v2->fbcoord[1] - e->v1->fbcoord[1]) > 0 ? \
+                       1 : \
+                       (e->v2->fbcoord[1] == e->v1->fbcoord[1] ? 0 : -1); \
+  while (nba)
+
+#define LRT_EDGE_BA_MARCHING_NEXT \
+  /* Marching along `e->v1` to `e->v2`, searching each possible bounding areas it may touch. */ \
+  nba = lineart_bounding_area_next(nba, e, x, y, k, positive_x, positive_y, &x, &y);
+
+#define LRT_EDGE_BA_MARCHING_END
+
 static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *e, int thread_id)
 {
-  double x = e->v1->fbcoord[0], y = e->v1->fbcoord[1];
-  LineartBoundingArea *ba = lineart_edge_first_bounding_area(rb, e);
-  LineartBoundingArea *nba = ba;
-  LineartTriangleThread *tri;
-
-  /* These values are used for marching along the line. */
-  double l, r;
-  double k = (e->v2->fbcoord[1] - e->v1->fbcoord[1]) /
-             (e->v2->fbcoord[0] - e->v1->fbcoord[0] + 1e-30);
-  int positive_x = (e->v2->fbcoord[0] - e->v1->fbcoord[0]) > 0 ?
-                       1 :
-                       (e->v2->fbcoord[0] == e->v1->fbcoord[0] ? 0 : -1);
-  int positive_y = (e->v2->fbcoord[1] - e->v1->fbcoord[1]) > 0 ?
-                       1 :
-                       (e->v2->fbcoord[1] == e->v1->fbcoord[1] ? 0 : -1);
-
-  while (nba) {
-
+  LRT_EDGE_BA_MARCHING_BEGIN
+  {
     for (int i = 0; i < nba->triangle_count; i++) {
       tri = (LineartTriangleThread *)nba->linked_triangles[i];
       /* If we are already testing the line in this thread, then don't do it. */
@@ -437,9 +444,9 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge *
         }
       }
     }
-    /* Marching along `e->v1` to `e->v2`, searching each possible bounding areas it may touch. */
-    nba = lineart_bounding_area_next(nba, e, x, y, k, positive_x, positive_y, &x, &y);
+    LRT_EDGE_BA_MARCHING_NEXT
   }
+  LRT_EDGE_BA_MARCHING_END
 }
 
 static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRenderTaskInfo *rti)
@@ -2161,46 +2168,41 @@ static void lineart_main_load_geometries(
     Scene *scene,
     Object *camera /* Still use camera arg for convenience. */,
     LineartRenderBuffer *rb,
-    bool allow_duplicates)
+    bool allow_duplicates,
+    bool do_shadow_casting)
 {
   double proj[4][4], view[4][4], result[4][4];
   float inv[4][4];
-  Camera *cam = camera->data;
-  float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
-  int fit = BKE_camera_sensor_fit(cam->sensor_fit, rb->w, rb->h);
-  double asp = ((double)rb->w / (double)rb->h);
 
-  int bound_box_discard_count = 0;
-
-  if (cam->type == CAM_PERSP) {
-    if (fit == CAMERA_SENSOR_FIT_VERT && asp > 1) {
-      sensor *= asp;
+  if (!do_shadow_casting) {
+    Camera *cam = camera->data;
+    float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
+    int fit = BKE_camera_sensor_fit(cam->sensor_fit, rb->w, rb->h);
+    double asp = ((double)rb->w / (double)rb->h);
+    if (cam->type == CAM_PERSP) {
+      if (fit == CAMERA_SENSOR_FIT_VERT && asp > 1) {
+        sensor *= asp;
+      }
+      if (fit == CAMERA_SENSOR_FIT_HOR && asp < 1) {
+        sensor /= asp;
+      }
+      double fov = focallength_to_fov(cam->lens / (1 + rb->overscan), sensor);


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list