commit 514a3ee5f8734b7de79993116dc2a09061d1c7e1
parent 2888a852fbdc55ed2adc14db6f783d7d72d34def
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Mon, 19 Sep 2016 13:33:52 +0200
BugFix: Reject some duplicate hits
Was on triangle's edge where the same hit was filtered twice.
Can lead to duplicate outputs.
Diffstat:
3 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/src/ssol_scene.c b/src/ssol_scene.c
@@ -287,9 +287,17 @@ hit_filter_function
/* these components have been set */
ASSERT_NAN(seg->dir, 3);
ASSERT_NAN(seg->org, 3);
+ ASSERT_NAN(&seg->tmin, 1);
ASSERT(seg->self_instance);
NCHECK(seg->self_front, 99);
+ /* need to reject identical hits on triangle's edges */
+ if (hit->distance <= seg->tmin) {
+ ASSERT(hit->distance == seg->tmin);
+ return 1;
+ }
+ seg->tmin = hit->distance;
+
/* Discard self intersection */
seg->hit_front = f3_dot(hit->normal, dir) < 0;
inst = *htable_instance_find(&rs->data.scene->instances_rt, &hit->prim.inst_id);
@@ -374,6 +382,7 @@ hit_filter_function
if(seg->hit_material->type == MATERIAL_VIRTUAL) {
return 1; /* Discard virtual material */
}
+
seg->hit_instance = inst;
return 0;
}
diff --git a/src/ssol_solver.c b/src/ssol_solver.c
@@ -199,6 +199,7 @@ check_fst_segment(const struct segment* seg)
NCHECK(seg->on_punched, 99);
ASSERT_NAN(seg->org, 3);
ASSERT(seg->weight > 0);
+ ASSERT_NAN(&seg->tmin, 1);
}
static void
@@ -238,6 +239,8 @@ setup_next_segment(struct realisation* rs)
seg->self_instance = prev->hit_instance;
seg->self_front = prev->hit_front;
seg->sun_segment = 0;
+ seg->tmin = -1; /* any valid tmin allowed */
+
d3_set(seg->org, prev->hit_pos);
res = material_shade(prev->hit_material, &data->fragment, rs->freq, data->brdfs);
@@ -270,6 +273,7 @@ reset_segment(struct segment* seg)
seg->self_instance = NULL;
seg->self_front = 99;
seg->weight = NAN;
+ seg->tmin = NAN;
#else
seg->hit = S3D_HIT_NULL;
#endif
@@ -510,6 +514,7 @@ receive_sunlight(struct realisation* rs)
seg->self_instance = start->instance;
seg->self_front = start->front_exposed;
seg->sun_segment = 1;
+ seg->tmin = -1; /* any valid tmin allowed */
/* search for occlusions from starting point */
ASSERT(rs->s_idx == 0); /* sun segment */
diff --git a/src/ssol_solver_c.h b/src/ssol_solver_c.h
@@ -66,6 +66,7 @@ struct segment {
double hit_pos[3];
double hit_pos_local[3]; /* in local coordinate, only set on punched shapes */
double hit_normal[3]; /* possibly reversed to face the incoming dir */
+ float tmin; /* used to reject duplicate hits in raytracing */
char hit_front; /* is the ending point of the segment on the front face? */
char self_front; /* was the starting point of the segment on the front face? */
char on_punched; /* is the hit on a punched shape? */