commit caff45f6a6d99beeeff7c85b0ed9bbbeac7e1933
parent a3f743987d61709209ed359eba7b2c1cf7d55208
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date: Fri, 27 Feb 2026 14:10:06 +0100
Implement LAMBERT BTDF and update path sampling
Implement an internal Lambertian bidirectional transmission distribution
function (BTDF), inspired by the Lambertian reflection model in the
star-sf.
Integrate the new function into the path sampling routine.
Diffstat:
| M | src/sphor_ran_bsdf.c | | | 107 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 106 insertions(+), 1 deletion(-)
diff --git a/src/sphor_ran_bsdf.c b/src/sphor_ran_bsdf.c
@@ -30,6 +30,104 @@
#include <star/ssf.h>
/*******************************************************************************
+ * Internal BSDFs
+ ******************************************************************************/
+
+/* BTDF LAMBERTIAN */
+struct lambertian_transmission {
+ double transmissivity;
+};
+
+static double
+lambertian_transmission_eval
+ (void* data,
+ const double wo[3],
+ const double N[3],
+ const double wi[3])
+{
+ struct lambertian_transmission* btdf = data;
+
+ ASSERT(NULL != data);
+ ASSERT(NULL != N);
+ ASSERT(NULL != wi);
+ ASSERT(d3_is_normalized(N) && d3_is_normalized(wi));
+ ASSERT(d3_dot(wi, N) < 0 && d3_dot(wo, N) > 0);
+ (void)wo, (void)N, (void)wi;
+
+ return btdf->transmissivity/ PI;
+}
+
+static double
+lambertian_transmission_sample
+ (void* data,
+ struct ssp_rng* rng,
+ const double wo[3],
+ const double N[3],
+ double wi[3],
+ int* type,
+ double* pdf)
+{
+ double sample[3];
+
+ ASSERT(NULL != data);
+ ASSERT(NULL != rng);
+ ASSERT(NULL != N);
+ ASSERT(NULL != wi);
+ ASSERT(d3_is_normalized(wo) && d3_is_normalized(N) && d3_dot(wo, N) > 0);
+ (void)wo;
+
+ ssp_ran_hemisphere_cos(rng, N, sample, pdf);
+ d3_muld(wi, sample, -1);
+ if (type) *type = SSF_TRANSMISSION | SSF_DIFFUSE;
+ return ((struct lambertian_transmission*)data)->transmissivity;
+}
+
+static double
+lambertian_transmission_pdf
+ (void* data,
+ const double wo[3],
+ const double N[3],
+ const double wi[3])
+{
+ double cos_wi_N;
+ ASSERT(NULL != data);
+ ASSERT(NULL != N);
+ ASSERT(NULL != wi);
+ ASSERT(d3_is_normalized(N) && d3_is_normalized(wi));
+ (void)data, (void)wo;
+
+ cos_wi_N = d3_dot(wi, N);
+ return cos_wi_N < 0.0 ? -cos_wi_N / PI : 0.0;
+}
+
+static res_T
+lambertian_transmission_setup
+ (struct ssf_bsdf* bsdf,
+ const double transmissivity)
+{
+ void* ptr = NULL;
+
+ ASSERT(NULL != bsdf);
+ ASSERT(0 <= transmissivity && transmissivity <=1);
+
+ ssf_bsdf_get_data(bsdf, &ptr);
+ struct lambertian_transmission* data = ptr;
+ data->transmissivity = transmissivity;
+
+ return RES_OK;
+}
+
+const struct ssf_bsdf_type lambertian_transmission = {
+ NULL,
+ NULL,
+ lambertian_transmission_sample,
+ lambertian_transmission_eval,
+ lambertian_transmission_pdf,
+ sizeof(struct lambertian_transmission),
+ ALIGNOF(struct lambertian_transmission)
+};
+
+/*******************************************************************************
* Helper functions
******************************************************************************/
static res_T
@@ -134,7 +232,6 @@ setup_bsdf_transmission
ASSERT(NULL != intersection);
(void)ray;
- (void)transmissivity;
(void)wavelength;
primitive = (struct primitive*)&intersection->position.primitive;
@@ -148,6 +245,13 @@ setup_bsdf_transmission
switch (btdf_dir) {
case SPHIN_BTDF_DIRECTION_LAMBERT:
+ res = ssf_bsdf_create
+ (sphor->allocator, &lambertian_transmission, &bsdf);
+ if (RES_OK != res) { goto error; }
+
+ res = lambertian_transmission_setup(bsdf, transmissivity);
+ if (RES_OK != res) { goto error; }
+
break;
case SPHIN_BTDF_DIRECTION_KEEP_CURRENT_DIR:
@@ -214,6 +318,7 @@ exit:
error:
goto exit;
}
+
/*******************************************************************************
* Local functions
******************************************************************************/