diff options
author | YimingWu <xp8110@outlook.com> | 2021-06-28 17:26:23 +0300 |
---|---|---|
committer | YimingWu <xp8110@outlook.com> | 2021-06-28 17:26:23 +0300 |
commit | cf21ba37efafbedc9e5d7f8624ce82370fe17a62 (patch) | |
tree | 4691123ee5fc43e8935b51c793d7e9b7b1aea9ec /source | |
parent | 9c6a382f9540c8e334a16b7740b5ba6bb294fca9 (diff) |
LineArt: Occlusion effectiveness support
This patch adds a function where you can specify occlusion effectiveness from 0 to 255 layers per face for a given mesh material.
Reviewed By: Sebastian Parborg (zeddb)
Ref D11308
Diffstat (limited to 'source')
10 files changed, 148 insertions, 110 deletions
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index b87ed9e431a..99f2592030e 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -101,8 +101,8 @@ static void generate_strokes_actual( lmd->use_multiple_levels ? lmd->level_end : lmd->level_start, lmd->target_material ? BKE_gpencil_object_material_index_get(ob, lmd->target_material) : 0, lmd->edge_types, - lmd->transparency_flags, - lmd->transparency_mask, + lmd->material_mask_flags, + lmd->material_mask_bits, lmd->thickness, lmd->opacity, lmd->source_vertex_group, @@ -411,7 +411,7 @@ static void occlusion_panel_draw(const bContext *UNUSED(C), Panel *panel) } } -static void transparency_panel_draw_header(const bContext *UNUSED(C), Panel *panel) +static void material_mask_panel_draw_header(const bContext *UNUSED(C), Panel *panel) { uiLayout *layout = panel->layout; PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); @@ -419,10 +419,10 @@ static void transparency_panel_draw_header(const bContext *UNUSED(C), Panel *pan const bool is_baked = RNA_boolean_get(ptr, "is_baked"); uiLayoutSetEnabled(layout, !is_baked); - uiItemR(layout, ptr, "use_transparency", 0, IFACE_("Transparency"), ICON_NONE); + uiItemR(layout, ptr, "use_material_mask", 0, IFACE_("Material Mask"), ICON_NONE); } -static void transparency_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void material_mask_panel_draw(const bContext *UNUSED(C), Panel *panel) { uiLayout *layout = panel->layout; PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); @@ -432,21 +432,21 @@ static void transparency_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); - uiLayoutSetEnabled(layout, RNA_boolean_get(ptr, "use_transparency")); + uiLayoutSetEnabled(layout, RNA_boolean_get(ptr, "use_material_mask")); uiLayout *row = uiLayoutRow(layout, true); uiLayoutSetPropDecorate(row, false); uiLayout *sub = uiLayoutRowWithHeading(row, true, IFACE_("Masks")); char text[2] = "0"; - PropertyRNA *prop = RNA_struct_find_property(ptr, "use_transparency_mask"); + PropertyRNA *prop = RNA_struct_find_property(ptr, "use_material_mask_bits"); for (int i = 0; i < 8; i++, text[0]++) { uiItemFullR(sub, ptr, prop, i, 0, UI_ITEM_R_TOGGLE, text, ICON_NONE); } uiItemL(row, "", ICON_BLANK1); /* Space for decorator. */ uiLayout *col = uiLayoutColumn(layout, true); - uiItemR(col, ptr, "use_transparency_match", 0, IFACE_("Match All Masks"), ICON_NONE); + uiItemR(col, ptr, "use_material_mask_match", 0, IFACE_("Match All Masks"), ICON_NONE); } static void face_mark_panel_draw_header(const bContext *UNUSED(C), Panel *panel) @@ -606,10 +606,10 @@ static void panelRegister(ARegionType *region_type) PanelType *occlusion_panel = gpencil_modifier_subpanel_register( region_type, "occlusion", "Occlusion", NULL, occlusion_panel_draw, panel_type); gpencil_modifier_subpanel_register(region_type, - "transparency", + "material_mask", "", - transparency_panel_draw_header, - transparency_panel_draw, + material_mask_panel_draw_header, + material_mask_panel_draw, occlusion_panel); gpencil_modifier_subpanel_register( region_type, "face_mark", "", face_mark_panel_draw_header, face_mark_panel_draw, panel_type); diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index d78cd862383..090c9d0f8fc 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -53,7 +53,8 @@ typedef struct LineartTriangle { double gn[3]; /* Material flag is removed to save space. */ - unsigned char transparency_mask; + unsigned char material_mask_bits; + unsigned char mat_occlusion; unsigned char flags; /* #eLineartTriangleFlags */ /** @@ -101,13 +102,8 @@ typedef struct LineartEdgeSegment { /** Occlusion level after "at" point */ unsigned char occlusion; - /** - * For determining lines behind a glass window material. - * the size of this variable should also be dynamically decided, 1 byte to 8 byte, - * allows 8 to 64 materials for "transparent mask". 1 byte (8 materials) should be - * enough for most cases. - */ - unsigned char transparency_mask; + /* Used to filter line art occlusion edges */ + unsigned char material_mask_bits; } LineartEdgeSegment; typedef struct LineartVert { @@ -177,7 +173,7 @@ typedef struct LineartEdgeChain { /** Chain now only contains one type of segments */ int type; - unsigned char transparency_mask; + unsigned char material_mask_bits; struct Object *object_ref; } LineartEdgeChain; @@ -191,7 +187,7 @@ typedef struct LineartEdgeChainItem { float normal[3]; unsigned char line_type; char occlusion; - unsigned char transparency_mask; + unsigned char material_mask_bits; size_t index; } LineartEdgeChainItem; @@ -616,8 +612,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache, int level_end, int mat_nr, short edge_types, - unsigned char transparency_flags, - unsigned char transparency_mask, + unsigned char material_mask_flags, + unsigned char material_mask_bits, short thickness, float opacity, const char *source_vgname, diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c index 37ee93b5f0f..d14f0e0c7bf 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c @@ -103,7 +103,7 @@ static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb, float *normal, char type, int level, - unsigned char transparency_mask, + unsigned char material_mask_bits, size_t index) { LineartEdgeChainItem *eci; @@ -115,7 +115,7 @@ static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb, LineartEdgeChainItem *old_rlci = ec->chain.last; old_rlci->line_type = type; old_rlci->occlusion = level; - old_rlci->transparency_mask = transparency_mask; + old_rlci->material_mask_bits = material_mask_bits; return old_rlci; } @@ -127,7 +127,7 @@ static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb, copy_v3_v3(eci->normal, normal); eci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE; eci->occlusion = level; - eci->transparency_mask = transparency_mask; + eci->material_mask_bits = material_mask_bits; BLI_addtail(&ec->chain, eci); return eci; @@ -140,7 +140,7 @@ static LineartEdgeChainItem *lineart_chain_prepend_point(LineartRenderBuffer *rb float *normal, char type, int level, - unsigned char transparency_mask, + unsigned char material_mask_bits, size_t index) { LineartEdgeChainItem *eci; @@ -157,7 +157,7 @@ static LineartEdgeChainItem *lineart_chain_prepend_point(LineartRenderBuffer *rb copy_v3_v3(eci->normal, normal); eci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE; eci->occlusion = level; - eci->transparency_mask = transparency_mask; + eci->material_mask_bits = material_mask_bits; BLI_addhead(&ec->chain, eci); return eci; @@ -228,7 +228,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) N, e->flags, es->occlusion, - es->transparency_mask, + es->material_mask_bits, e->v1_obindex); while (ba && (new_e = lineart_line_get_connected(ba, new_vt, &new_vt, e->flags))) { new_e->flags |= LRT_EDGE_FLAG_CHAIN_PICKED; @@ -263,16 +263,16 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) N, new_e->flags, es->occlusion, - es->transparency_mask, + es->material_mask_bits, new_e->v1_obindex); last_occlusion = es->occlusion; - last_transparency = es->transparency_mask; + last_transparency = es->material_mask_bits; } } else if (new_vt == new_e->v2) { es = new_e->segments.first; last_occlusion = es->occlusion; - last_transparency = es->transparency_mask; + last_transparency = es->material_mask_bits; es = es->next; for (; es; es = es->next) { double gpos[3], lpos[3]; @@ -291,7 +291,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) last_transparency, new_e->v2_obindex); last_occlusion = es->occlusion; - last_transparency = es->transparency_mask; + last_transparency = es->material_mask_bits; } VERT_COORD_TO_FLOAT(new_e->v2); lineart_chain_prepend_point(rb, @@ -326,7 +326,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) * of the line. */ es = e->segments.first; last_occlusion = ((LineartEdgeSegment *)es)->occlusion; - last_transparency = ((LineartEdgeSegment *)es)->transparency_mask; + last_transparency = ((LineartEdgeSegment *)es)->material_mask_bits; for (es = es->next; es; es = es->next) { double gpos[3], lpos[3]; double *lfb = e->v1->fbcoord, *rfb = e->v2->fbcoord; @@ -341,10 +341,10 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) N, e->flags, es->occlusion, - es->transparency_mask, + es->material_mask_bits, e->v1_obindex); last_occlusion = es->occlusion; - last_transparency = es->transparency_mask; + last_transparency = es->material_mask_bits; } VERT_COORD_TO_FLOAT(e->v2) lineart_chain_append_point(rb, @@ -385,10 +385,10 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) if (new_vt == new_e->v1) { es = new_e->segments.last; last_occlusion = es->occlusion; - last_transparency = es->transparency_mask; + last_transparency = es->material_mask_bits; /* Fix leading vertex occlusion. */ eci->occlusion = last_occlusion; - eci->transparency_mask = last_transparency; + eci->material_mask_bits = last_transparency; for (es = new_e->segments.last; es; es = es->prev) { double gpos[3], lpos[3]; double *lfb = new_e->v1->fbcoord, *rfb = new_e->v2->fbcoord; @@ -396,7 +396,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at); interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at); last_occlusion = es->prev ? es->prev->occlusion : last_occlusion; - last_transparency = es->prev ? es->prev->transparency_mask : last_transparency; + last_transparency = es->prev ? es->prev->material_mask_bits : last_transparency; POS_TO_FLOAT(lpos, gpos) lineart_chain_append_point(rb, ec, @@ -412,9 +412,9 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) else if (new_vt == new_e->v2) { es = new_e->segments.first; last_occlusion = es->occlusion; - last_transparency = es->transparency_mask; + last_transparency = es->material_mask_bits; eci->occlusion = last_occlusion; - eci->transparency_mask = last_transparency; + eci->material_mask_bits = last_transparency; es = es->next; for (; es; es = es->next) { double gpos[3], lpos[3]; @@ -430,10 +430,10 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb) N, new_e->flags, es->occlusion, - es->transparency_mask, + es->material_mask_bits, new_e->v2_obindex); last_occlusion = es->occlusion; - last_transparency = es->transparency_mask; + last_transparency = es->material_mask_bits; } VERT_COORD_TO_FLOAT(new_e->v2) lineart_chain_append_point(rb, @@ -574,12 +574,12 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb) BLI_addtail(&rb->chains, ec); LineartEdgeChainItem *first_rlci = (LineartEdgeChainItem *)ec->chain.first; int fixed_occ = first_rlci->occlusion; - unsigned char fixed_mask = first_rlci->transparency_mask; + unsigned char fixed_mask = first_rlci->material_mask_bits; ec->level = fixed_occ; - ec->transparency_mask = fixed_mask; + ec->material_mask_bits = fixed_mask; for (eci = first_rlci->next; eci; eci = next_rlci) { next_rlci = eci->next; - if (eci->occlusion != fixed_occ || eci->transparency_mask != fixed_mask) { + if (eci->occlusion != fixed_occ || eci->material_mask_bits != fixed_mask) { if (next_rlci) { if (lineart_point_overlapping(next_rlci, eci->pos[0], eci->pos[1], 1e-5)) { continue; @@ -589,7 +589,7 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb) /* Set the same occlusion level for the end vertex, so when further connection is needed * the backwards occlusion info is also correct. */ eci->occlusion = fixed_occ; - eci->transparency_mask = fixed_mask; + eci->material_mask_bits = fixed_mask; /* No need to split at the last point anyway. */ break; } @@ -614,9 +614,9 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb) new_rlc->type = ec->type; ec = new_rlc; fixed_occ = eci->occlusion; - fixed_mask = eci->transparency_mask; + fixed_mask = eci->material_mask_bits; ec->level = fixed_occ; - ec->transparency_mask = fixed_mask; + ec->material_mask_bits = fixed_mask; } } } @@ -683,7 +683,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf LineartEdgeChain *ec, LineartEdgeChainItem *eci, int occlusion, - unsigned char transparency_mask, + unsigned char material_mask_bits, float dist, float *result_new_len, LineartBoundingArea *caller_ba) @@ -712,7 +712,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf continue; } if (cre->ec == ec || (!cre->ec->chain.first) || (cre->ec->level != occlusion) || - (cre->ec->transparency_mask != transparency_mask)) { + (cre->ec->material_mask_bits != material_mask_bits)) { continue; } if (!rb->fuzzy_everything) { @@ -749,7 +749,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf LISTBASE_FOREACH (LinkData *, ld, list) { \ LineartBoundingArea *sba = (LineartBoundingArea *)ld->data; \ adjacent_closest = lineart_chain_get_closest_cre( \ - rb, sba, ec, eci, occlusion, transparency_mask, dist, &adjacent_new_len, ba); \ + rb, sba, ec, eci, occlusion, material_mask_bits, dist, &adjacent_new_len, ba); \ if (adjacent_new_len < dist) { \ dist = adjacent_new_len; \ closest_cre = adjacent_closest; \ @@ -782,7 +782,7 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb) float dist = rb->chaining_image_threshold; float dist_l, dist_r; int occlusion, reverse_main; - unsigned char transparency_mask; + unsigned char material_mask_bits; ListBase swap = {0}; if (rb->chaining_image_threshold < 0.0001) { @@ -806,16 +806,16 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb) } occlusion = ec->level; - transparency_mask = ec->transparency_mask; + material_mask_bits = ec->material_mask_bits; rlci_l = ec->chain.first; rlci_r = ec->chain.last; while ((ba_l = lineart_bounding_area_get_end_point(rb, rlci_l)) && (ba_r = lineart_bounding_area_get_end_point(rb, rlci_r))) { closest_cre_l = lineart_chain_get_closest_cre( - rb, ba_l, ec, rlci_l, occlusion, transparency_mask, dist, &dist_l, NULL); + rb, ba_l, ec, rlci_l, occlusion, material_mask_bits, dist, &dist_l, NULL); closest_cre_r = lineart_chain_get_closest_cre( - rb, ba_r, ec, rlci_r, occlusion, transparency_mask, dist, &dist_r, NULL); + rb, ba_r, ec, rlci_r, occlusion, material_mask_bits, dist, &dist_r, NULL); if (closest_cre_l && closest_cre_r) { if (dist_l < dist_r) { closest_cre = closest_cre_l; @@ -949,12 +949,12 @@ void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshol eci->normal, eci->line_type, ec->level, - eci->transparency_mask, + eci->material_mask_bits, eci->index); new_rlc->object_ref = ec->object_ref; new_rlc->type = ec->type; new_rlc->level = ec->level; - new_rlc->transparency_mask = ec->transparency_mask; + new_rlc->material_mask_bits = ec->material_mask_bits; ec = new_rlc; } } diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index d1bb18e3fed..fbfbb5145e6 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -146,8 +146,12 @@ static LineartEdgeSegment *lineart_give_segment(LineartRenderBuffer *rb) /** * Cuts the edge in image space and mark occlusion level for each segment. */ -static void lineart_edge_cut( - LineartRenderBuffer *rb, LineartEdge *e, double start, double end, uchar transparency_mask) +static void lineart_edge_cut(LineartRenderBuffer *rb, + LineartEdge *e, + double start, + double end, + uchar material_mask_bits, + uchar mat_occlusion) { LineartEdgeSegment *es, *ies, *next_es, *prev_es; LineartEdgeSegment *cut_start_before = 0, *cut_end_before = 0; @@ -240,7 +244,7 @@ static void lineart_edge_cut( /* Insert cutting points for when a new cut is needed. */ ies = cut_start_before->prev ? cut_start_before->prev : NULL; ns->occlusion = ies ? ies->occlusion : 0; - ns->transparency_mask = ies->transparency_mask; + ns->material_mask_bits = ies->material_mask_bits; BLI_insertlinkbefore(&e->segments, cut_start_before, ns); } /* Otherwise we already found a existing cutting point, no need to insert a new one. */ @@ -250,7 +254,7 @@ static void lineart_edge_cut( * append the new cut to the end. */ ies = e->segments.last; ns->occlusion = ies->occlusion; - ns->transparency_mask = ies->transparency_mask; + ns->material_mask_bits = ies->material_mask_bits; BLI_addtail(&e->segments, ns); } if (cut_end_before) { @@ -258,14 +262,14 @@ static void lineart_edge_cut( if (cut_end_before != ns2) { ies = cut_end_before->prev ? cut_end_before->prev : NULL; ns2->occlusion = ies ? ies->occlusion : 0; - ns2->transparency_mask = ies ? ies->transparency_mask : 0; + ns2->material_mask_bits = ies ? ies->material_mask_bits : 0; BLI_insertlinkbefore(&e->segments, cut_end_before, ns2); } } else { ies = e->segments.last; ns2->occlusion = ies->occlusion; - ns2->transparency_mask = ies->transparency_mask; + ns2->material_mask_bits = ies->material_mask_bits; BLI_addtail(&e->segments, ns2); } @@ -282,8 +286,8 @@ static void lineart_edge_cut( /* Register 1 level of occlusion for all touched segments. */ for (es = ns; es && es != ns2; es = es->next) { - es->occlusion++; - es->transparency_mask |= transparency_mask; + es->occlusion += mat_occlusion; + es->material_mask_bits |= material_mask_bits; } /* Reduce adjacent cutting points of the same level, which saves memory. */ @@ -293,7 +297,7 @@ static void lineart_edge_cut( next_es = es->next; if (prev_es && prev_es->occlusion == es->occlusion && - prev_es->transparency_mask == es->transparency_mask) { + prev_es->material_mask_bits == es->material_mask_bits) { BLI_remlink(&e->segments, es); /* This puts the node back to the render buffer, if more cut happens, these unused nodes get * picked first. */ @@ -373,7 +377,11 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge * tri = (LineartTriangleThread *)nba->linked_triangles[i]; /* If we are already testing the line in this thread, then don't do it. */ if (tri->testing_e[thread_id] == e || (tri->base.flags & LRT_TRIANGLE_INTERSECTION_ONLY) || - lineart_occlusion_is_adjacent_intersection(e, (LineartTriangle *)tri)) { + /* Ignore this triangle if an intersection line directly comes from it, */ + lineart_occlusion_is_adjacent_intersection(e, (LineartTriangle *)tri) || + /* Or if this triangle isn't effectively occluding anything nor it's providing a + material flag. */ + ((!tri->base.mat_occlusion) && (!tri->base.material_mask_bits))) { continue; } tri->testing_e[thread_id] = e; @@ -389,7 +397,7 @@ static void lineart_occlusion_single_line(LineartRenderBuffer *rb, LineartEdge * rb->shift_y, &l, &r)) { - lineart_edge_cut(rb, e, l, r, tri->base.transparency_mask); + lineart_edge_cut(rb, e, l, r, tri->base.material_mask_bits, tri->base.mat_occlusion); 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. */ @@ -726,7 +734,7 @@ static void lineart_triangle_post(LineartTriangle *tri, LineartTriangle *orig) /* Just re-assign normal and set cull flag. */ copy_v3_v3_db(tri->gn, orig->gn); tri->flags = LRT_CULL_GENERATED; - tri->transparency_mask = orig->transparency_mask; + tri->material_mask_bits = orig->material_mask_bits; } static void lineart_triangle_set_cull_flag(LineartTriangle *tri, uchar flag) @@ -1782,11 +1790,15 @@ static void lineart_geometry_object_load(LineartObjectInfo *obi, LineartRenderBu loop = loop->next; tri->v[2] = &orv[BM_elem_index_get(loop->v)]; - /* Transparency bit assignment. */ + /* Material mask bits and occlusion effectiveness assignment. */ Material *mat = BKE_object_material_get(orig_ob, f->mat_nr + 1); - tri->transparency_mask = ((mat && (mat->lineart.flags & LRT_MATERIAL_TRANSPARENCY_ENABLED)) ? - mat->lineart.transparency_mask : - 0); + tri->material_mask_bits |= ((mat && (mat->lineart.flags & LRT_MATERIAL_MASK_ENABLED)) ? + mat->lineart.material_mask_bits : + 0); + tri->mat_occlusion |= ((mat && + (mat->lineart.flags & LRT_MATERIAL_CUSTOM_OCCLUSION_EFFECTIVENESS)) ? + mat->lineart.mat_occlusion : + 1); double gn[3]; copy_v3db_v3fl(gn, f->no); @@ -4172,8 +4184,8 @@ static void lineart_gpencil_generate(LineartCache *cache, Object *source_object, Collection *source_collection, int types, - uchar transparency_flags, - uchar transparency_mask, + uchar material_mask_flags, + uchar material_mask_bits, short thickness, float opacity, const char *source_vgname, @@ -4229,14 +4241,14 @@ static void lineart_gpencil_generate(LineartCache *cache, continue; } } - if (transparency_flags & LRT_GPENCIL_TRANSPARENCY_ENABLE) { - if (transparency_flags & LRT_GPENCIL_TRANSPARENCY_MATCH) { - if (ec->transparency_mask != transparency_mask) { + if (material_mask_flags & LRT_GPENCIL_MATERIAL_MASK_ENABLE) { + if (material_mask_flags & LRT_GPENCIL_MATERIAL_MASK_MATCH) { + if (ec->material_mask_bits != material_mask_bits) { continue; } } else { - if (!(ec->transparency_mask & transparency_mask)) { + if (!(ec->material_mask_bits & material_mask_bits)) { continue; } } @@ -4335,8 +4347,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache, int level_end, int mat_nr, short edge_types, - uchar transparency_flags, - uchar transparency_mask, + uchar material_mask_flags, + uchar material_mask_bits, short thickness, float opacity, const char *source_vgname, @@ -4384,8 +4396,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache, source_object, source_collection, use_types, - transparency_flags, - transparency_mask, + material_mask_flags, + material_mask_bits, thickness, opacity, source_vgname, diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c index 7ebb869e955..b0ead0013d8 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c @@ -143,8 +143,8 @@ static bool bake_strokes(Object *ob, lmd->use_multiple_levels ? lmd->level_end : lmd->level_start, lmd->target_material ? BKE_gpencil_object_material_index_get(ob, lmd->target_material) : 0, lmd->edge_types, - lmd->transparency_flags, - lmd->transparency_mask, + lmd->material_mask_flags, + lmd->material_mask_bits, lmd->thickness, lmd->opacity, lmd->source_vertex_group, diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index f12d5e44a3c..0bd7e500044 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -883,11 +883,11 @@ typedef enum eLineArtGPencilModifierFlags { LRT_GPENCIL_USE_CACHE = (1 << 4), } eLineArtGPencilModifierFlags; -typedef enum eLineartGpencilTransparencyFlags { - LRT_GPENCIL_TRANSPARENCY_ENABLE = (1 << 0), - /** Set to true means using "and" instead of "or" logic on mask bits. */ - LRT_GPENCIL_TRANSPARENCY_MATCH = (1 << 1), -} eLineartGpencilTransparencyFlags; +typedef enum eLineartGpencilMaterialMaskFlags { + LRT_GPENCIL_MATERIAL_MASK_ENABLE = (1 << 0), + /** When set, material mask bit comparisons are done with bit wise "AND" instead of "OR". */ + LRT_GPENCIL_MATERIAL_MASK_MATCH = (1 << 1), +} eLineartGpencilMaterialMaskFlags; struct LineartCache; @@ -918,8 +918,8 @@ typedef struct LineartGpencilModifierData { float opacity; short thickness; - unsigned char transparency_flags; /* eLineartGpencilTransparencyFlags */ - unsigned char transparency_mask; + unsigned char material_mask_flags; /* eLineartGpencilMaterialMaskFlags */ + unsigned char material_mask_bits; /** `0..1` range for cosine angle */ float crease_threshold; diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 5bc8370a159..62933d44afd 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -146,13 +146,21 @@ typedef enum eMaterialGPencilStyle_Mode { } eMaterialGPencilStyle_Mode; typedef struct MaterialLineArt { - int flags; /* eMaterialLineArtFlags */ - unsigned char transparency_mask; - unsigned char _pad[3]; + /* eMaterialLineArtFlags */ + int flags; + + /* Used to filter line art occlusion edges */ + unsigned char material_mask_bits; + + /** Maximum 255 levels of equavalent occlusion. */ + unsigned char mat_occlusion; + + unsigned char _pad[2]; } MaterialLineArt; typedef enum eMaterialLineArtFlags { - LRT_MATERIAL_TRANSPARENCY_ENABLED = (1 << 0), + LRT_MATERIAL_MASK_ENABLED = (1 << 0), + LRT_MATERIAL_CUSTOM_OCCLUSION_EFFECTIVENESS = (1 << 1), } eMaterialLineArtFlags; typedef struct Material { diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index 84120a54da4..57abf708f60 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -134,3 +134,6 @@ DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame) * global_areas. See D9442. */ DNA_STRUCT_RENAME_ELEM(wmWindow, global_area_map, global_areas) DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, line_types, edge_types) +DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_flags, material_mask_flags) +DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_mask, material_mask_bits) +DNA_STRUCT_RENAME_ELEM(MaterialLineArt, transparency_mask, material_mask_bits) diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 6fd897a3d66..7c5c6d26bd6 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -2997,20 +2997,22 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); - prop = RNA_def_property(srna, "use_transparency", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transparency_flags", LRT_GPENCIL_TRANSPARENCY_ENABLE); + prop = RNA_def_property(srna, "use_material_mask", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna( + prop, NULL, "material_mask_flags", LRT_GPENCIL_MATERIAL_MASK_ENABLE); RNA_def_property_ui_text( - prop, "Use Transparency", "Use transparency mask from this material in line art"); + prop, "Use Material Mask", "Use material masks to filter out occluded strokes"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); - prop = RNA_def_property(srna, "use_transparency_match", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transparency_flags", LRT_GPENCIL_TRANSPARENCY_MATCH); + prop = RNA_def_property(srna, "use_material_mask_match", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna( + prop, NULL, "material_mask_flags", LRT_GPENCIL_MATERIAL_MASK_MATCH); RNA_def_property_ui_text( - prop, "Match Transparency", "Require matching all transparency masks instead of just one"); + prop, "Match Masks", "Require matching all material masks instead of just one"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); - prop = RNA_def_property(srna, "use_transparency_mask", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1); + prop = RNA_def_property(srna, "use_material_mask_bits", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "material_mask_bits", 1); RNA_def_property_array(prop, 8); RNA_def_property_ui_text(prop, "Mask", ""); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index a4052430d9a..b662f54ed4c 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -688,19 +688,36 @@ static void rna_def_material_lineart(BlenderRNA *brna) RNA_def_struct_sdna(srna, "MaterialLineArt"); RNA_def_struct_ui_text(srna, "Material Line Art", ""); - prop = RNA_def_property(srna, "use_transparency", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_material_mask", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_default(prop, 0); - RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_MATERIAL_TRANSPARENCY_ENABLED); + RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_MATERIAL_MASK_ENABLED); RNA_def_property_ui_text( - prop, "Use Transparency", "Use transparency mask from this material in line art"); + prop, "Use Material Mask", "Use material masks to filter out occluded strokes"); RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update"); - prop = RNA_def_property(srna, "use_transparency_mask", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_material_mask_bits", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_default(prop, 0); - RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1); + RNA_def_property_boolean_sdna(prop, NULL, "material_mask_bits", 1); RNA_def_property_array(prop, 8); RNA_def_property_ui_text(prop, "Mask", ""); RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update"); + + prop = RNA_def_property(srna, "use_mat_occlusion", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_default(prop, 0); + RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_MATERIAL_CUSTOM_OCCLUSION_EFFECTIVENESS); + RNA_def_property_ui_text(prop, + "Custom Occlusion Effectiveness", + "Use custom occlusion effectiveness for this material"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update"); + + prop = RNA_def_property(srna, "mat_occlusion", PROP_INT, PROP_NONE); + RNA_def_property_int_default(prop, 1); + RNA_def_property_ui_range(prop, 0.0f, 5.0f, 1.0f, 1); + RNA_def_property_ui_text( + prop, + "Effectiveness", + "Faces with this material will behave as if it has set number of layers in occlusion"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update"); } void RNA_def_material(BlenderRNA *brna) |