star-phor

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

commit 78e6b89f34cc0cf007dbe1c2cc42d9f43360d60c
parent 78fb646db0002954a6eccd63b3627c047f506467
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date:   Mon,  6 Apr 2026 10:16:57 +0200

Fix: Ensure SSF direction convention in star-sf function calls

The star-phor ray directions were already consistently treated to comply
with the SSF API for calculations. However, in some star-sf function
calls when computing Fresnel terms for interface-ray interaction
samples, the raw, untreated normal directions were used. This resulted
in potentially incorrect Fresnel term calculations and physically
inconsistent reflectivity and transmissivity values.

This commit corrects this issue by using the treated normal direction
consistently within star-sf functions and includes a check to ensure
physically plausible reflectivity and transmissivity values.

Diffstat:
Msrc/sphor_interface.c | 36++++++++++++++++++++++++------------
Msrc/sphor_ran_bsdf.c | 4++--
2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/src/sphor_interface.c b/src/sphor_interface.c @@ -379,11 +379,12 @@ primitive_get_reflectivity struct primitive* primitive, double wavelength, double cos_theta, - double* reflectivity) + double* out_reflectivity) { double eta_i = 0, k_i = 0; double eta_t = 0, k_t = 0; - double refrel = 0; + double refr_wl = 0; + double reflectivity = 0; enum sphin_brdf_reflectivity_type reflectivity_type = SPHIN_BRDF_REFLECTIVITY_NONE__; struct sphin_brdf* brdf = NULL; @@ -393,7 +394,7 @@ primitive_get_reflectivity ASSERT(NULL != sphor); ASSERT(NULL != primitive); - ASSERT(NULL != reflectivity); + ASSERT(NULL != out_reflectivity); res = primitive_get_brdf(sphor, primitive, &brdf); if (RES_OK != res) { goto error; } @@ -414,14 +415,14 @@ primitive_get_reflectivity res = sphin_spectral_property_interpolate_at_wavelength (reflectivity_spectrum, wavelength, - SPHIN_INTERPOLATION_LINEAR, &refrel); + SPHIN_INTERPOLATION_LINEAR, &refr_wl); if (RES_OK != res) { goto error; } res = ssf_fresnel_create (sphor->allocator, &ssf_fresnel_constant, &fresnel); if (RES_OK != res) { goto error; } - res = ssf_fresnel_constant_setup(fresnel, refrel); + res = ssf_fresnel_constant_setup(fresnel, refr_wl); if (RES_OK != res) { goto error; } break; @@ -477,9 +478,14 @@ primitive_get_reflectivity break; } - *reflectivity = ssf_fresnel_eval(fresnel, cos_theta); + reflectivity = ssf_fresnel_eval(fresnel, cos_theta); + if (reflectivity > 1 || reflectivity < 0) { + res = RES_BAD_ARG; + goto error; + } exit: + *out_reflectivity = reflectivity; if (NULL != fresnel) { ssf_fresnel_ref_put(fresnel); } @@ -494,11 +500,12 @@ primitive_get_transmissivity struct primitive* primitive, double wavelength, double cos_theta, - double* transmissivity) + double* out_transmissivity) { double eta_i = 0, k_i = 0; double eta_t = 0, k_t = 0; - double transm = 0; + double transm_wl = 0; + double transmissivity = 0; enum sphin_btdf_transmissivity_type transmissivity_type = SPHIN_BTDF_TRANSMISSIVITY_NONE__; struct sphin_btdf* btdf = NULL; @@ -508,7 +515,7 @@ primitive_get_transmissivity ASSERT(NULL != sphor); ASSERT(NULL != primitive); - ASSERT(NULL != transmissivity); + ASSERT(NULL != out_transmissivity); res = primitive_get_btdf(sphor, primitive, &btdf); if (RES_OK != res) { goto error; } @@ -529,14 +536,14 @@ primitive_get_transmissivity res = sphin_spectral_property_interpolate_at_wavelength (transmissivity_spectrum, wavelength, - SPHIN_INTERPOLATION_LINEAR, &transm); + SPHIN_INTERPOLATION_LINEAR, &transm_wl); if (RES_OK != res) { goto error; } res = ssf_fresnel_create (sphor->allocator, &ssf_fresnel_constant, &fresnel); if (RES_OK != res) { goto error; } - res = ssf_fresnel_constant_setup(fresnel, 1. - transm); + res = ssf_fresnel_constant_setup(fresnel, 1. - transm_wl); if (RES_OK != res) { goto error; } break; @@ -592,9 +599,14 @@ primitive_get_transmissivity break; } - *transmissivity = 1 - ssf_fresnel_eval(fresnel, cos_theta); + transmissivity = 1 - ssf_fresnel_eval(fresnel, cos_theta); + if (transmissivity > 1 || transmissivity < 0) { + res = RES_BAD_ARG; + goto error; + } exit: + *out_transmissivity = transmissivity; if (NULL != fresnel) { ssf_fresnel_ref_put(fresnel); } diff --git a/src/sphor_ran_bsdf.c b/src/sphor_ran_bsdf.c @@ -661,7 +661,7 @@ sample_interface_ray_interaction if (NULL != brdf) { res = primitive_get_reflectivity (sphor, primitive, wavelength, - d3_dot(normal, ray->direction), &reflectivity); + d3_dot(normal, wo), &reflectivity); if (RES_OK != res) { goto error; } } @@ -669,7 +669,7 @@ sample_interface_ray_interaction if (NULL != btdf) { res = primitive_get_transmissivity (sphor, primitive, wavelength, - d3_dot(normal, ray->direction), &transmissivity); + d3_dot(normal, wo), &transmissivity); if (RES_OK != res) { goto error; } }