[Bf-blender-cvs] [da02b2ed5b7] temp-lineart-embree: LineArt: Embree wip runnable
YimingWu
noreply at git.blender.org
Tue Mar 15 14:53:57 CET 2022
Commit: da02b2ed5b713189a50450d2db001fca964ce4ed
Author: YimingWu
Date: Tue Mar 15 21:53:22 2022 +0800
Branches: temp-lineart-embree
https://developer.blender.org/rBda02b2ed5b713189a50450d2db001fca964ce4ed
LineArt: Embree wip runnable
===================================================================
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 9d9f8a494ae..61836c00017 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -237,6 +237,7 @@ typedef struct LineartOcclusionPairRecord {
LineartOcclusionPair *array;
uint32_t next;
uint32_t max_length;
+ uint32_t scheduled_next;
} LineartOcclusionPairRecord;
typedef struct LineartRenderBuffer {
@@ -416,6 +417,10 @@ typedef struct LineartRenderTaskInfo {
ListBase edge_mark;
ListBase floating;
+ /* Range: [start, end) */
+ size_t ocpair_index_start;
+ size_t ocpair_index_end;
+
} LineartRenderTaskInfo;
typedef struct LineartObjectInfo {
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index ae5a5a6393a..3f262732138 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -427,20 +427,36 @@ static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRend
BLI_spin_lock(&rb->lock_task);
-#define LRT_ASSIGN_OCCLUSION_TASK(name) \
- if (rb->name.last) { \
- data = rb->name.last; \
- rti->name.first = (void *)data; \
- for (i = 0; i < LRT_THREAD_EDGE_COUNT && data; i++) { \
- data = data->next; \
- } \
- rti->name.last = data; \
- rb->name.last = data; \
- res = 1; \
- } \
- else { \
- rti->name.first = rti->name.last = NULL; \
+#ifdef LINEART_USE_EMBREE
+
+ LineartOcclusionPairRecord *rec = &rb->occlusion_record;
+ if (rec->scheduled_next >= rec->next) {
+ res = 0;
}
+ else {
+ rti->ocpair_index_start = rec->scheduled_next;
+ size_t length = MIN2(LRT_THREAD_EDGE_COUNT, rec->next - rec->scheduled_next);
+ rec->scheduled_next += length;
+ rti->ocpair_index_end = rti->ocpair_index_start + length;
+ res = 1;
+ }
+
+#else
+
+# define LRT_ASSIGN_OCCLUSION_TASK(name) \
+ if (rb->name.last) { \
+ data = rb->name.last; \
+ rti->name.first = (void *)data; \
+ for (i = 0; i < LRT_THREAD_EDGE_COUNT && data; i++) { \
+ data = data->next; \
+ } \
+ rti->name.last = data; \
+ rb->name.last = data; \
+ res = 1; \
+ } \
+ else { \
+ rti->name.first = rti->name.last = NULL; \
+ }
LRT_ASSIGN_OCCLUSION_TASK(contour);
LRT_ASSIGN_OCCLUSION_TASK(intersection);
@@ -449,7 +465,9 @@ static int lineart_occlusion_make_task_info(LineartRenderBuffer *rb, LineartRend
LRT_ASSIGN_OCCLUSION_TASK(edge_mark);
LRT_ASSIGN_OCCLUSION_TASK(floating);
-#undef LRT_ASSIGN_OCCLUSION_TASK
+# undef LRT_ASSIGN_OCCLUSION_TASK
+
+#endif
BLI_spin_unlock(&rb->lock_task);
@@ -463,6 +481,37 @@ static void lineart_occlusion_worker(TaskPool *__restrict UNUSED(pool), LineartR
while (lineart_occlusion_make_task_info(rb, rti)) {
+#ifdef LINEART_USE_EMBREE
+ double l, r;
+
+ LineartOcclusionPairRecord *rec = &rb->occlusion_record;
+ for (size_t i = rti->ocpair_index_start; i < rti->ocpair_index_end; i++) {
+ LineartOcclusionPair *op = &rec->array[i];
+ if (lineart_triangle_edge_image_space_occlusion(&rb->lock_task,
+ op->t,
+ op->e,
+ rb->camera_pos,
+ rb->cam_is_persp,
+ rb->allow_overlapping_edges,
+ rb->view_projection,
+ rb->view_vector,
+ rb->shift_x,
+ rb->shift_y,
+ &l,
+ &r)) {
+ BLI_spin_lock(&rb->lock_task);
+ lineart_edge_cut(rb, op->e, l, r, op->t->material_mask_bits, op->t->mat_occlusion);
+ BLI_spin_unlock(&rb->lock_task);
+ if (op->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. */
+ continue;
+ }
+ }
+ }
+
+#else
+
for (eip = rti->contour.first; eip && eip != rti->contour.last; eip = eip->next) {
lineart_occlusion_single_line(rb, eip, rti->thread_id);
}
@@ -486,6 +535,8 @@ static void lineart_occlusion_worker(TaskPool *__restrict UNUSED(pool), LineartR
for (eip = rti->floating.first; eip && eip != rti->floating.last; eip = eip->next) {
lineart_occlusion_single_line(rb, eip, rti->thread_id);
}
+
+#endif /* embree */
}
}
@@ -1436,6 +1487,11 @@ static void lineart_main_discard_out_of_frame_edges(LineartRenderBuffer *rb)
e[i].flags = LRT_EDGE_FLAG_CHAIN_PICKED;
}
}
+ if (eln->flags & LRT_ELEMENT_IS_ADDITIONAL) {
+ /* XXX: Technically this is incorrect because this way embree doesn't take into account of
+ * post-clipping edges. */
+ continue;
+ }
lineart_embree_new_virtual_geometry(rb, eln);
}
}
@@ -2288,7 +2344,7 @@ static void lineart_embree_new_virtual_geometry(LineartRenderBuffer *rb,
LineartElementLinkNode *e_eln)
{
RTCGeometry geom = rtcNewGeometry(rb->rtcdevice, RTC_GEOMETRY_TYPE_USER);
- uint32_t geom_id = rtcAttachGeometry(rb->rtcscene_geom, geom);
+ uint32_t geom_id = rtcAttachGeometry(rb->rtcscene_view, geom);
rtcSetGeometryUserData(geom, e_eln);
rtcSetGeometryUserPrimitiveCount(geom, e_eln->element_count);
@@ -2599,13 +2655,16 @@ OcclusionCollideFunc(void *userPtr, struct RTCCollision *collisions, unsigned in
collisions[i].primID0 == collisions[i].primID1) {
continue;
}
- /* Continue from here. */
- RTCGeometry g_edge = rtcGetGeometry(rb->rtcscene_geom, collisions[i].geomID0);
- RTCGeometry g_triangle = rtcGetGeometry(rb->rtcscene_view, collisions[i].geomID1);
+ /* Continue from here. */
+ RTCGeometry g_edge = rtcGetGeometry(rb->rtcscene_view, collisions[i].geomID0);
+ RTCGeometry g_triangle = rtcGetGeometry(rb->rtcscene_geom, collisions[i].geomID1);
LineartElementLinkNode *eln_edge = rtcGetGeometryUserData(g_edge);
- LineartElementLinkNode *eln_triangle = rtcGetGeometryUserData(g_triangle);
- if (eln_triangle->flags & LRT_ELEMENT_IS_EDGE) {
+ LineartPointArrayFinal *rec = rtcGetGeometryUserData(g_triangle);
+ LineartElementLinkNode *eln_triangle = rec->eln_triangle;
+
+ /* This is actually incorrect? */
+ if (UNLIKELY(eln_triangle->flags & LRT_ELEMENT_IS_EDGE)) {
SWAP(LineartElementLinkNode *, eln_edge, eln_triangle);
}
@@ -2613,7 +2672,8 @@ OcclusionCollideFunc(void *userPtr, struct RTCCollision *collisions, unsigned in
* float. */
LineartEdge *prim_edge = &((LineartEdge *)eln_edge->pointer)[collisions[i].primID0];
LineartTriangle *tri = eln_triangle->pointer;
- LineartTriangle *prim_triangle = (void *)(((uchar *)tri) + rb->triangle_size);
+ LineartTriangle *prim_triangle = (void *)(((uchar *)tri) +
+ rb->triangle_size * collisions[i].primID1);
LineartPointArrayFinal *geom_triangle = &rb->mesh_record.array[collisions[i].geomID1];
float pa[9];
@@ -4676,8 +4736,6 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
lineart_embree_generate_occlusion_pairs(rb);
- lineart_embree_clear_mesh_record(rb);
-
#endif
/* Link lines to acceleration structure, this can only be done after perspective division, if
@@ -4694,6 +4752,11 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
/* Occlusion is work-and-wait. This call will not return before work is completed. */
lineart_main_occlusion_begin(rb);
+#ifdef LINEART_USE_EMBREE
+ /* Do this after occlusion because we need occlusion pairs available. */
+ lineart_embree_clear_mesh_record(rb);
+#endif
+
/* Chaining is all single threaded. See lineart_chain.c
* In this particular call, only lines that are geometrically connected (share the _exact_
* same end point) will be chained together. */
More information about the Bf-blender-cvs
mailing list