[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