[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