commit ac075b7a5d6c7be763d0128c1eae6c1f5fa34a2b
parent 8f0c06484abee2a53a1e250d9604f08c936fe802
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date: Fri, 16 Jan 2026 17:08:19 +0100
Set more restrictive rules in the filter function
Add a new rule to the filter function to prevent photons from being
trapped at a given position when they are too close to a triangle edge.
This type of self-intersection cannot be filtered by the previous rules,
since the intersected primitive is different from the one where the
photon originates.
Now, rays that intersect a given primitive are discarded if the
intersection distance is below a given epsilon and the intersection
point is too close to one of the edges. The intersection point is
evaluated using the barycentric coordinates of the hit on the primitive,
which always range between 0 and 1, making the test independent of the
characteristic size of the geometry.
Also ensure that the ray distance respects the defined range.
Diffstat:
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/sphor_config.c b/src/sphor_config.c
@@ -36,6 +36,8 @@
struct s3d_scene_view;
struct suniq;
+const double UV_EPS = 1e-6;
+
/*******************************************************************************
* Helper functions
******************************************************************************/
@@ -531,15 +533,31 @@ hit_filter_function
void* primitive_id,
void* interface)
{
+ double u = 0;
+ double v = 0;
+
(void)pos;
(void)dir;
- (void)range;
(void)interface;
size_t* prim_id = primitive_id;
+ /* Discard hits that do not respect the range — this may happen due to
+ * numerical precision errors in Embree. */
+ if(hit->distance <= range[0] || hit->distance >= range[1])
+ return 1;
+
+ /* Discard auto-intersection */
if (hit->prim.prim_id == *prim_id) { return 1; }
+ /* Discard intersections of photons trapped in the edges of two primitives */
+ u = hit->uv[0];
+ v = hit->uv[1];
+ if (hit->distance < UV_EPS
+ && (u < UV_EPS || v < UV_EPS || (u + v) > 1.0 - UV_EPS)) {
+ return 1;
+ }
+
return 0;
}