star-sf

Set of surface and volume scattering functions
git clone git://git.meso-star.fr/star-sf.git
Log | Files | Refs | README | LICENSE

commit b81ccffe8f2cb5674edce6e6f22c114129b003f7
parent 3d1898266c762fb499aeaf86694d47df7def855b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 19 Sep 2016 16:38:26 +0200

Update the API of the B<x|S>DF eval/pdf functions

Add the surface normal parameter.

Diffstat:
Msrc/ssf.h | 6++++++
Msrc/ssf_bsdf_view.c | 18++++++++++++------
Msrc/ssf_bxdf.c | 22+++++++++++++++-------
Msrc/ssf_specular_reflection.c | 17+++++++++++------
Msrc/test_ssf_bsdf.c | 2++
Msrc/test_ssf_bsdf_view.c | 5++---
Msrc/test_ssf_bxdf.c | 8++++++--
Msrc/test_ssf_specular_reflection.c | 4++--
Msrc/test_ssf_utils.h | 16++++++++++++----
9 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/src/ssf.h b/src/ssf.h @@ -64,12 +64,14 @@ struct ssf_bxdf_type { (*eval) (void* bxdf, const double wi[3], /* Normalized incoming dir. Point inward the surface */ + const double N[3], /* Normalized surface normal */ const double wo[3]);/* Normalized outgoing dir. Point outward the surface */ double (*pdf) (void* bxdf, const double wi[3], /* Normalized incoming dir. Point inward the surface */ + const double N[3], /* Normalized surface normal */ const double wo[3]);/* Normalized outgoing dir. Point outward the surface */ size_t sizeof_bxdf; /* In Bytes */ @@ -160,12 +162,14 @@ SSF_API double /* Reflectivity */ ssf_bsdf_view_eval (struct ssf_bsdf_view* view, const double wi[3], /* Normalized incoming direction */ + const double N[3], /* Normalized surface normal */ const double wo[3]); /* Normalized outgoing direction */ SSF_API double ssf_bsdf_view_pdf (struct ssf_bsdf_view* view, const double wi[3], /* Normalized incoming direction */ + const double N[3], /* Normalized surface normal */ const double wo[3]); /* Normalized outgoing direction */ /******************************************************************************* @@ -244,12 +248,14 @@ SSF_API double /* Reflectivity */ ssf_bxdf_eval (struct ssf_bxdf* bxdf, const double wi[3], /* Normalized incoming dir. Point inward the surface */ + const double N[3], /* Normalized surface normal */ const double wo[3]);/* Normalized outgoing dir. Point outward the surface */ SSF_API double /* Probability */ ssf_bxdf_pdf (struct ssf_bxdf* bxdf, const double wi[3], /* Normalized incoming dir. Point inward the surface */ + const double N[3], /* Normalized surface normal */ const double wo[3]);/* Normalized outgoing dir. Point outward the surface */ /* Retrieve the internal data of the BxDF. Usefull for user defined BxDFs on diff --git a/src/ssf_bsdf_view.c b/src/ssf_bsdf_view.c @@ -166,8 +166,8 @@ ssf_bsdf_view_sample /* Add the contribution of the others components */ FOR_EACH(i, 0, view->ncomponents) { if(i == icomponent) continue; - pdf += ssf_bxdf_pdf(view->components[i], wi, wo) * view->probas[i]; - reflectivity += ssf_bxdf_eval(view->components[i], wi, wo) * view->probas[i]; + pdf += ssf_bxdf_pdf(view->components[i], wi, N, wo) * view->probas[i]; + reflectivity += ssf_bxdf_eval(view->components[i], wi, N, wo) * view->probas[i]; } wo[3] = pdf; return reflectivity / pdf; @@ -175,7 +175,10 @@ ssf_bsdf_view_sample double ssf_bsdf_view_eval - (struct ssf_bsdf_view* view, const double wi[3], const double wo[3]) + (struct ssf_bsdf_view* view, + const double wi[3], + const double N[3], + const double wo[3]) { double R = 0; size_t i; @@ -183,14 +186,17 @@ ssf_bsdf_view_eval ASSERT(d3_is_normalized(wi) && d3_is_normalized(wo)); FOR_EACH(i, 0, view->ncomponents) { - R += ssf_bxdf_eval(view->components[i], wi, wo) * view->probas[i]; + R += ssf_bxdf_eval(view->components[i], wi, N, wo) * view->probas[i]; } return R; } double ssf_bsdf_view_pdf - (struct ssf_bsdf_view* view, const double wi[3], const double wo[3]) + (struct ssf_bsdf_view* view, + const double wi[3], + const double N[3], + const double wo[3]) { double pdf = 0; size_t i; @@ -198,7 +204,7 @@ ssf_bsdf_view_pdf ASSERT(d3_is_normalized(wi) && d3_is_normalized(wo)); FOR_EACH(i, 0, view->ncomponents) { - pdf += ssf_bxdf_pdf(view->components[i], wi, wo) * view->probas[i]; + pdf += ssf_bxdf_pdf(view->components[i], wi, N, wo) * view->probas[i]; } return pdf; } diff --git a/src/ssf_bxdf.c b/src/ssf_bxdf.c @@ -128,19 +128,27 @@ ssf_bxdf_sample } double -ssf_bxdf_eval(struct ssf_bxdf* bxdf, const double wi[3], const double wo[3]) +ssf_bxdf_eval + (struct ssf_bxdf* bxdf, + const double wi[3], + const double N[3], + const double wo[3]) { - ASSERT(bxdf && wi && wo); - ASSERT(d3_is_normalized(wi) && d3_is_normalized(wo)); - return bxdf->type.eval(bxdf->data, wi, wo); + ASSERT(bxdf && wi && N && wo); + ASSERT(d3_is_normalized(wi) && d3_is_normalized(N) && d3_is_normalized(wo)); + return bxdf->type.eval(bxdf->data, wi, N, wo); } double -ssf_bxdf_pdf(struct ssf_bxdf* bxdf, const double wi[3], const double wo[3]) +ssf_bxdf_pdf + (struct ssf_bxdf* bxdf, + const double wi[3], + const double N[3], + const double wo[3]) { ASSERT(bxdf && wi && wo); - ASSERT(d3_is_normalized(wi) && d3_is_normalized(wo)); - return bxdf->type.pdf(bxdf->data, wi, wo); + ASSERT(d3_is_normalized(wi) && d3_is_normalized(N) && d3_is_normalized(wo)); + return bxdf->type.pdf(bxdf->data, wi, N, wo); } res_T diff --git a/src/ssf_specular_reflection.c b/src/ssf_specular_reflection.c @@ -49,28 +49,33 @@ specular_reflection_sample { struct specular_reflection* brdf = data; double cosi; + double dir[3]; ASSERT(u >= 0 && u < 1 && v >= 0 && v < 1 && wi && N && wo); + ASSERT(d3_is_normalized(wi) && d3_is_normalized(N)); (void)u, (void)v; /* Reflection the incoming direction w[3] with respect to the normal */ cosi = -d3_dot(wi, N); - d3_muld(wo, N, 2*cosi); - d3_add(wo, wo, wi); + d3_muld(dir, N, 2*cosi); + d3_add(dir, dir, wi); + d3_set(wo, dir); wo[3] = 1.0; /* pdf */ return brdf->reflectivity; } static double -specular_reflection_eval(void* data, const double wi[3], const double wo[3]) +specular_reflection_eval + (void* data, const double wi[3], const double N[3], const double wo[3]) { - (void)data, (void)wi, (void)wo; + (void)data, (void)wi, (void)N, (void)wo; return 0.0; } static double -specular_reflection_pdf(void* data, const double wi[3], const double wo[3]) +specular_reflection_pdf + (void* data, const double wi[3], const double N[3], const double wo[3]) { - (void)data, (void)wi, (void)wo; + (void)data, (void)wi, (void)N, (void)wo; return 0.0; } diff --git a/src/test_ssf_bsdf.c b/src/test_ssf_bsdf.c @@ -61,6 +61,8 @@ main(int argc, char** argv) d3(N, 0.0, 1.0, 0.0); CHECK(ssf_bsdf_view_sample(view, 0, 0, w, N, dir), 0.123); CHECK(ssf_bsdf_view_sample(view, 0.5, 0.5, w, N, dir), 0.123); + CHECK(ssf_bsdf_view_eval(view, w, N, dir), 0); + CHECK(ssf_bsdf_view_pdf(view, w, N, dir), 0); CHECK(ssf_bsdf_clear(NULL), RES_BAD_ARG); CHECK(ssf_bsdf_clear(bsdf), RES_OK); diff --git a/src/test_ssf_bsdf_view.c b/src/test_ssf_bsdf_view.c @@ -77,8 +77,8 @@ main(int argc, char** argv) const double u = rand_canonic(); const double v = rand_canonic(); const double weight = ssf_bsdf_view_sample(view, u, v, w, N, dir); - CHECK(ssf_bsdf_view_eval(view, w, dir), 0); - CHECK(ssf_bsdf_view_pdf(view, w, dir), 0); + CHECK(ssf_bsdf_view_eval(view, w, N, dir), 0); + CHECK(ssf_bsdf_view_pdf(view, w, N, dir), 0); sum += weight; sqr_sum += weight*weight; } @@ -87,7 +87,6 @@ main(int argc, char** argv) SE = sqrt(V / (double)NSTEPS); CHECK(eq_eps((0.1234+0.6789) * 0.5, E, SE), 1); - CHECK(ssf_bsdf_view_ref_get(NULL), RES_BAD_ARG); CHECK(ssf_bsdf_view_ref_get(view), RES_OK); CHECK(ssf_bsdf_view_ref_put(NULL), RES_BAD_ARG); diff --git a/src/test_ssf_bxdf.c b/src/test_ssf_bxdf.c @@ -75,6 +75,7 @@ static double bxdf_eval (void* bxdf, const double wi[3], + const double N[3], const double wo[3]) { struct bxdf* BxDF = bxdf; @@ -82,6 +83,7 @@ bxdf_eval NCHECK(wi, NULL); NCHECK(wo, NULL); CHECK(d3_eq(BxDF->wi, wi), 1); + CHECK(d3_eq(BxDF->N, N), 1); CHECK(d3_eq(BxDF->wo, wo), 1); return BxDF->value; } @@ -90,6 +92,7 @@ static double bxdf_pdf (void* bxdf, const double wi[3], + const double N[3], const double wo[3]) { struct bxdf* BxDF = bxdf; @@ -97,6 +100,7 @@ bxdf_pdf NCHECK(wi, NULL); NCHECK(wo, NULL); CHECK(d3_eq(BxDF->wi, wi), 1); + CHECK(d3_eq(BxDF->N, N), 1); CHECK(d3_eq(BxDF->wo, wo), 1); return BxDF->pdf; } @@ -192,9 +196,9 @@ main(int argc, char** argv) d3_normalize(dir, dir); d3_set(data->wo, dir); data->value = 4.567; - CHECK(ssf_bxdf_eval(bxdf, w, dir), data->value); + CHECK(ssf_bxdf_eval(bxdf, w, N, dir), data->value); data->pdf = 8.90; - CHECK(ssf_bxdf_pdf(bxdf, w, dir), data->pdf); + CHECK(ssf_bxdf_pdf(bxdf, w, N, dir), data->pdf); CHECK(bxdf_is_init, 1); CHECK(ssf_bxdf_ref_put(bxdf), RES_OK); diff --git a/src/test_ssf_specular_reflection.c b/src/test_ssf_specular_reflection.c @@ -50,8 +50,8 @@ main(int argc, char** argv) CHECK(ssf_bxdf_sample(brdf, 0, 0, w, N, dir), 0.123); CHECK(d3_eq_eps(d3(w, w[0], -w[1], 0.0), dir, 1.e-6), 1); - CHECK(ssf_bxdf_eval(brdf, w, dir), 0.0); - CHECK(ssf_bxdf_pdf(brdf, w, dir), 0.0); + CHECK(ssf_bxdf_eval(brdf, w, N, dir), 0.0); + CHECK(ssf_bxdf_pdf(brdf, w, N, dir), 0.0); d3(w, 0.0, -1.0, 0.0); CHECK(ssf_bxdf_sample(brdf, 0, 0, w, N, dir), 0.123); diff --git a/src/test_ssf_utils.h b/src/test_ssf_utils.h @@ -49,16 +49,24 @@ bxdf_dummy_sample } static double -bxdf_dummy_eval(void* bxdf, const double wi[3], const double wo[3]) +bxdf_dummy_eval + (void* bxdf, + const double wi[3], + const double N[3], + const double wo[3]) { - (void)bxdf, (void)wi, (void)wo; + (void)bxdf, (void)wi, (void)N, (void)wo; return 0.0; } static double -bxdf_dummy_pdf(void* bxdf, const double wi[3], const double wo[3]) +bxdf_dummy_pdf + (void* bxdf, + const double wi[3], + const double N[3], + const double wo[3]) { - (void)bxdf, (void)wi, (void)wo; + (void)bxdf, (void)wi, (void)N, (void)wo; return 0.0; }