Commit: 08f5361d746084fafbc127ce8d31b6aa65791a5a Author: YimingWu Date: Fri Apr 8 11:16:30 2022 +0800 Branches: lineart-shadow https://developer.blender.org/rB08f5361d746084fafbc127ce8d31b6aa65791a5a
LineArt: WIP shadow matching. =================================================================== M source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h M source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c M source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h M source/blender/gpencil_modifiers/intern/lineart/lineart_util.c M source/blender/makesdna/DNA_lineart_types.h =================================================================== diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 7549362baf2..0dce7636843 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -159,8 +159,6 @@ typedef enum eLineArtVertFlags { } eLineArtVertFlags; typedef struct LineartEdge { - /** We only need link node kind of list here. */ - struct LineartEdge *next; struct LineartVert *v1, *v2; /** * Local vertex index for two ends, not pouting in #RenderVert because all verts are loaded, so @@ -175,6 +173,13 @@ typedef struct LineartEdge { uint16_t flags; uint8_t intersection_mask; + /** Matches the shadow result, used to determine whether a line is in the shadow or not. + * Usages: + * - Intersection lines: ((e->t1->target_reference << 32) | e->t2->target_reference); + * - Other lines: LRT_EDGE_IDENTIFIER(obi, e); + * - After shadow calculation: (search the shadow result and set reference to that); + */ + struct LineartEdge *from_shadow; int target_reference; /** @@ -306,6 +311,7 @@ typedef struct LineartRenderBuffer { /* Render status */ double view_vector[3]; + double view_vector_secondary[3]; /* For shadow. */ int triangle_size; @@ -350,6 +356,10 @@ typedef struct LineartRenderBuffer { bool use_loose; bool use_light_contour; bool use_shadow; + bool use_contour_secondary; /* From viewing camera, during shadow calculation. */ + + bool needs_shadow_separation; + bool fuzzy_intersections; bool fuzzy_everything; bool allow_boundaries; @@ -374,8 +384,12 @@ typedef struct LineartRenderBuffer { /* Keep an copy of these data so when line art is running it's self-contained. */ bool cam_is_persp; + bool cam_is_persp_secondary; /* "Secondary" ones are from viewing camera (as opposed to shadow + camera), during shadow calculation. */ float cam_obmat[4][4]; + float cam_obmat_secondary[4][4]; double camera_pos[3]; + double camera_pos_secondary[3]; double active_camera_pos[3]; /* Stroke offset calculation may use active or selected camera. */ double near_clip, far_clip; float shift_x, shift_y; @@ -461,6 +475,9 @@ 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))) typedef struct LineartObjectInfo { struct LineartObjectInfo *next; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index 2f24326bbf4..a382771c01b 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -1618,6 +1618,24 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, edge_flag_result |= LRT_EDGE_FLAG_CONTOUR; } + if (rb->use_contour_secondary) { + if (rb->cam_is_persp_secondary) { + sub_v3_v3v3_db(view_vector, vert->gloc, rb->camera_pos_secondary); + } + else { + view_vector = rb->view_vector_secondary; + } + + dot_1 = dot_v3v3_db(view_vector, tri1->gn); + 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; + } + } + if (!only_contour) { if (rb->use_crease) { @@ -2436,6 +2454,7 @@ static void lineart_geometry_object_load_no_bmesh(LineartObjectInfo *ob_info, } la_edge->flags = use_type; la_edge->object_ref = orig_ob; + la_edge->from_shadow = (LineartEdge *)LRT_EDGE_IDENTIFIER(ob_info, la_edge); BLI_addtail(&la_edge->segments, la_seg); if (usage == OBJECT_LRT_INHERIT || usage == OBJECT_LRT_INCLUDE || usage == OBJECT_LRT_NO_INTERSECTION) { @@ -2958,7 +2977,8 @@ static void lineart_main_load_geometries( 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. */ + * get the same reference to the same object. Also because we increse this count before + * assigning, it ensures we can use 0x0 as a invalid value for identifying special cases. */ obindex++; LineartObjectInfo *obi = lineart_mem_acquire(&rb->render_data_pool, sizeof(LineartObjectInfo)); @@ -3831,6 +3851,19 @@ static void lineart_main_get_view_vector(LineartRenderBuffer *rb) mul_v3_mat3_m4v3(trans, inv, direction); copy_m4_m4(rb->cam_obmat, obmat_no_scale); copy_v3db_v3fl(rb->view_vector, trans); + + if (rb->use_contour_secondary) { + copy_m4_m4(obmat_no_scale, rb->cam_obmat_secondary); + + normalize_v3(obmat_no_scale[0]); + normalize_v3(obmat_no_scale[1]); + normalize_v3(obmat_no_scale[2]); + invert_m4_m4(inv, obmat_no_scale); + transpose_m4(inv); + mul_v3_mat3_m4v3(trans, inv, direction); + copy_m4_m4(rb->cam_obmat_secondary, obmat_no_scale); + copy_v3db_v3fl(rb->view_vector_secondary, trans); + } } static void lineart_destroy_render_data(LineartRenderBuffer *rb) @@ -4852,6 +4885,9 @@ static void lineart_create_edges_from_isec_data(LineartIsecData *d) e->v2 = v2; e->t1 = is->tri1; e->t2 = is->tri2; + /* This is so we can also match intersection edges from shadow to later viewing stage. */ + e->from_shadow = (LineartEdge *)((((uint64_t)e->t1->target_reference) << 32) | + e->t2->target_reference); e->flags = LRT_EDGE_FLAG_INTERSECTION; e->intersection_mask = (is->tri1->intersection_mask | is->tri2->intersection_mask); BLI_addtail(&e->segments, es); @@ -5278,6 +5314,10 @@ static void lineart_shadow_create_container_array(LineartRenderBuffer *rb) int segment_count = 0; LRT_ITER_ALL_LINES_BEGIN { + /* Only contour and loose edges can actually cast shadows. */ + if (!(e->flags & (LRT_EDGE_FLAG_CONTOUR | LRT_EDGE_FLAG_LOOSE))) { + continue; + } LISTBASE_FOREACH (LineartEdgeSegment *, es, &e->segments) { DISCARD_NONSENSE_SEGMENTS segment_count++; @@ -5293,6 +5333,9 @@ static void lineart_shadow_create_container_array(LineartRenderBuffer *rb) int i = 0; LRT_ITER_ALL_LINES_BEGIN { + if (!(e->flags & (LRT_EDGE_FLAG_CONTOUR | LRT_EDGE_FLAG_LOOSE))) { + continue; + } LISTBASE_FOREACH (LineartEdgeSegment *, es, &e->segments) { DISCARD_NONSENSE_SEGMENTS @@ -5862,6 +5905,9 @@ static bool lineart_main_try_generate_shadow(Depsgraph *depsgraph, rb->do_shadow_cast = true; rb->shadow_data_pool = shadow_data_pool; + copy_v3_v3_db(rb->camera_pos_secondary, rb->camera_pos); + copy_m4_m4(rb->cam_obmat_secondary, rb->cam_obmat); + copy_m4_m4(rb->cam_obmat, lmd->light_contour_object->obmat); copy_v3db_v3fl(rb->camera_pos, rb->cam_obmat[3]); rb->cam_is_persp = is_persp; @@ -5878,10 +5924,16 @@ static bool lineart_main_try_generate_shadow(Depsgraph *depsgraph, rb->far_clip = 200.0f; } rb->tile_recursive_level = is_persp ? LRT_TILE_RECURSIVE_PERSPECTIVE : LRT_TILE_RECURSIVE_ORTHO; - rb->use_crease = rb->use_material = rb->use_edge_marks = rb->use_intersections = - rb->use_light_contour = false; + + /* Contour and loose edge from light viewing direction will be casted as shadow, so only force + * them on. Other line types are enabled as-is if preserving lit/shaded information is required + * for those feature lines. */ + if (!rb->needs_shadow_separation) { + rb->use_crease = rb->use_material = rb->use_edge_marks = rb->use_intersections = + rb->use_light_contour = false; + } rb->use_loose = true; - rb->use_contour = true; /* Only contour from light viewing direction will be casted as shadow. */ + rb->use_contour = true; rb->max_occlusion_level = 0; /* No point getting see-through projections there. */ rb->use_back_face_culling = false; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h index 660f12340e8..1eceed553a0 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h @@ -51,7 +51,6 @@ void *lineart_mem_acquire(struct LineartStaticMemPool *smp, size_t size); void *lineart_mem_acquire_thread(struct LineartStaticMemPool *smp, size_t size); void lineart_mem_destroy(struct LineartStaticMemPool *smp); -void lineart_prepend_edge_direct(void **list_head, void *node); void lineart_prepend_pool(LinkNode **first, struct LineartStaticMemPool *smp, void *link); void lineart_matrix_ortho_44d(double (*mProjection)[4], diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c index eed9e11c1a4..5bf7b54a193 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_util.c @@ -146,13 +146,6 @@ void lineart_mem_destroy(LineartStaticMemPool *smp) } } -void lineart_prepend_edge_direct(void **list_head, void *node) -{ - LineartEdge *e_n = (LineartEdge *)node; - e_n->next = (*list_head); - (*list_head) = e_n; -} - void lineart_prepend_pool(LinkNode **first, LineartStaticMemPool *smp, void *link) { LinkNode *ln = lineart_mem_acquire_thread(smp, sizeof(LinkNode)); diff --git a/source/blender/makesdna/DNA_lineart_types.h b/source/blender/makesdna/DNA_lineart_types.h index 903748b3aa8..1a57307d430 100644 --- a/source/blender/makesdna/DNA_lineart_types.h +++ b/source/blender/makesdna/DNA_lineart_types.h @@ -60,6 +60,7 @@ typedef enum eLineart @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs