star-phor

Radiative transfer solver for photoreactors.
git clone https://www.edstar.cnrs.fr/git/star-phor.git
Log | Files | Refs | README | LICENSE

commit 94a5f9e25a3f1859ec2113a70bf5fe17cdcac3f9
parent bc2abf06454e245f12a300a471eb982b61e7e542
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date:   Fri, 23 Jan 2026 12:19:35 +0100

Fix absorption handling after BRDF ray-intersection

Previously, the code assumed that ssf_bsdf_sample would return a
TRANSMISSION flag based on the reflectivity of the BRDF. This assumption
was incorrect: rays that should have been absorbed could continue,
leading to incorrect path termination.

This commit corrects the behavior by explicitly performing a Bernoulli
trial using the BRDF reflectivity. The ray is either reflected or
absorbed according to this probability.

Diffstat:
Msrc/sphor_compute_mvrea.c | 20+++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/src/sphor_compute_mvrea.c b/src/sphor_compute_mvrea.c @@ -311,7 +311,7 @@ setup_MVREA_accums res = setup_MVREA_volumes_accum(sphor, accum2id, accums); if (RES_OK != res) { goto error; } - /* One accum per sensor volume; all components of the volume contribute + /* One accum per sensor volume; all components of the volume contribute * to the accum */ res = setup_MVREA_per_volume_accums(sphor, accum2id, accums); if (RES_OK != res) { goto error; } @@ -570,6 +570,7 @@ sample_interface_ray_interaction double normal[3] = {0}; double wo[3] = {0}; double pdf = 0; + double reflectivity = 0; double sample[3] = {0}; int flag = 0; struct primitive* primitive = NULL; @@ -586,8 +587,8 @@ sample_interface_ray_interaction primitive = &intersection->position.primitive; /* Ensure that the ray direction and the geometry normal are compatible with - * th star-sf library. */ - d3_muld(wo, ray->direction,-1); + * the star-sf library. */ + d3_muld(wo, ray->direction, -1); d3_set(normal, primitive->normal); /* Ensure normal and direction point to the same hemisphere */ invert_normal = (d3_dot(normal, wo) > 0 ) ? 1. : -1.; @@ -617,15 +618,16 @@ sample_interface_ray_interaction if (RES_OK != res) { goto error; } } - ssf_bsdf_sample(bsdf, rng, wo, normal, sample, &flag, &pdf); + reflectivity = ssf_bsdf_sample(bsdf, rng, wo, normal, sample, &flag, &pdf); - if (flag & SSF_TRANSMISSION) { - if (NULL != brdf) { - *interaction_type = RAY_INTERFACE_INTERACTION_ABSORPTION; - } + if (NULL != brdf) { + if (ssp_rng_canonical(rng) < reflectivity) { + *interaction_type = RAY_INTERFACE_INTERACTION_REFLECTION; } else { - *interaction_type = RAY_INTERFACE_INTERACTION_TRANSMISSION; } + *interaction_type = RAY_INTERFACE_INTERACTION_ABSORPTION; } } + else if (flag & SSF_TRANSMISSION) { + *interaction_type = RAY_INTERFACE_INTERACTION_TRANSMISSION; } else if (flag & SSF_REFLECTION) { *interaction_type = RAY_INTERFACE_INTERACTION_REFLECTION; } else { res = RES_BAD_ARG; }