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 c2b41c82fcd97a70809fd6cab03a29b618046c8e
parent 4b6658c8ca704f84aa45a57726b0c5de8cdf6dd2
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Tue,  4 Oct 2016 21:13:54 +0200

The pdf of the sampled specular reflection is infinity

Rewrite some comments and add some tests to the lambertian BxDF

Diffstat:
Msrc/ssf.h | 27+++++++++++----------------
Msrc/ssf_bsdf.c | 12++++++------
Msrc/ssf_microfacet_reflection.c | 8--------
Msrc/ssf_specular_reflection.c | 3+--
Msrc/test_ssf_lambertian_reflection.c | 11++++-------
Msrc/test_ssf_specular_reflection.c | 12++++++------
6 files changed, 28 insertions(+), 45 deletions(-)

diff --git a/src/ssf.h b/src/ssf.h @@ -55,12 +55,8 @@ struct ssf_bxdf_type { res_T (*init)(struct mem_allocator* allocator, void* bxdf); void (*release)(void* bxdf); - /* Sample an incoming direction `wi' with respect to the outgoing direction - * `wo'. Return the direction reflectance along 'wi'. Note that the - * directional reflectance is *not* the value of the BxDF wrt to 'wo' - * and 'wi'. It is the ratio between the reflected and the incoming radiance - * (i.e. Li / Lo), while the BxDF is the constant of proportionality between - * the reflected radiance and the incoming irradiance (i.e. Lo / Eo) */ + /* Sample a direction `wi' wrt `wo' whose pdf is BxDF(wo, wi) |wi.n|. Return + * the value of BxDF(wo, wi) */ double (*sample) (void* bxdf, @@ -78,6 +74,7 @@ struct ssf_bxdf_type { const double N[3], /* Normalized surface normal */ const double wi[3]);/* Normalized incoming direction */ + /* Probability density function */ double (*pdf) (void* bxdf, @@ -200,10 +197,9 @@ SSF_API res_T ssf_bsdf_clear (struct ssf_bsdf* bsdf); -/* Return the directional reflectance, i.e. the ratio between the reflected - * and the incoming radiance (Li/Lo). Note that this is different to the - * BSDF value that is the ratio between the reflected radiance and the incoming - * irradiance, i.e. Li/Eo */ +/* Sample a direction `wi' wrt `wo' whose pdf is BSDF(wo, wi) |wi.n|. Return + * the directionnal reflectance, i.e. pdf to be reflected in *any* direction + * wrt to the incident direction `wi' */ SSF_API double ssf_bsdf_sample (struct ssf_bsdf* bsdf, @@ -220,7 +216,7 @@ ssf_bsdf_eval const double N[3], /* Normalized surface normal */ const double wi[3]); /* Normalized incoming direction */ -SSF_API double +SSF_API double /* Probability density function*/ ssf_bsdf_pdf (struct ssf_bsdf* bsdf, const double wo[3], /* Normalized incoming direction */ @@ -247,10 +243,9 @@ SSF_API res_T ssf_bxdf_ref_put (struct ssf_bxdf* bxdf); -/* Return the directionnal reflectance, i.e. the ratio between the reflected - * and the incoming radiance (Li/Lo). Note that this is different to the - * BxDF value that is the ratio between the reflected radiance and the incoming - * irradiance, i.e. Li/Eo */ +/* Sample a direction `wi' wrt `wo' whose pdf is BxDF(wo, wi) |wi.n|. Return + * the directionnal reflectance, i.e. pdf to be reflected in *any* direction + * wrt to the incident direction `wi' */ SSF_API double ssf_bxdf_sample (struct ssf_bxdf* bxdf, @@ -267,7 +262,7 @@ ssf_bxdf_eval const double N[3], /* Normalized surface normal */ const double wi[3]);/* Normalized incoming direction */ -SSF_API double /* Probability */ +SSF_API double /* Probability density function */ ssf_bxdf_pdf (struct ssf_bxdf* bxdf, const double wo[3], /* Normalized outgoing direction */ diff --git a/src/ssf_bsdf.c b/src/ssf_bsdf.c @@ -151,7 +151,7 @@ ssf_bsdf_sample double* out_pdf) { double cumul[MAX_BxDFs]; - double R_wi; + double R; double r; double pdf; size_t i; @@ -181,9 +181,9 @@ ssf_bsdf_sample } /* Sample a direction from the selected component */ - R_wi = ssf_bxdf_sample(bsdf->bxdfs[i], rng, wo, N, wi, &pdf); + R = ssf_bxdf_sample(bsdf->bxdfs[i], rng, wo, N, wi, &pdf); *out_pdf = pdf*bsdf->weights[i]; - return R_wi; + return R; } double @@ -210,13 +210,13 @@ ssf_bsdf_eval const double N[3], const double wi[3]) { - double R = 0; + double fr = 0; size_t i; ASSERT(bsdf); bsdf_normalize_weights(bsdf); FOR_EACH(i, 0, bsdf->nbxdfs) { - R += bsdf->weights[i] * ssf_bxdf_eval(bsdf->bxdfs[i], wo, N, wi); + fr += bsdf->weights[i] * ssf_bxdf_eval(bsdf->bxdfs[i], wo, N, wi); } - return R; + return fr; } diff --git a/src/ssf_microfacet_reflection.c b/src/ssf_microfacet_reflection.c @@ -120,14 +120,6 @@ microfacet_reflection_pdf return pdf_wh / (4.0*fabs(d3_dot(wo, wh))); } -static FINLINE double -microfacet_reflection_rho(void* data, const double wo[3], const double N[3]) -{ - ASSERT(data && wo && N); - (void)data, (void)wo, (void)N; - return 0; /* TODO */ -} - /******************************************************************************* * Microfacet 2 functions ******************************************************************************/ diff --git a/src/ssf_specular_reflection.c b/src/ssf_specular_reflection.c @@ -60,10 +60,9 @@ specular_reflection_sample /* Reflect the outgoing direction wo with respect to the surface normal N */ reflect(wi, wo, N); - *pdf = 1.0; /* pdf */ + *pdf = INF; cos_wi_N = cos_wo_N = d3_dot(wo, N); - /* TODO check this */ return cos_wo_N > 0 ? ssf_fresnel_eval(brdf->fresnel, cos_wi_N) : 0; } diff --git a/src/test_ssf_lambertian_reflection.c b/src/test_ssf_lambertian_reflection.c @@ -115,16 +115,13 @@ main(int argc, char** argv) CHECK(eq_eps(E, 2.0/4.0, 2.0*SE), 1); CHECK(eq_eps(SE, 1.0/sqrt((double)NSTEPS) * sqrt(1.0/3.0 - 1.0/4.0), 1.e-6), 1); - sum = sum_sqr = 0; FOR_EACH(i, 0, NSTEPS) { + double val; R = ssf_bxdf_sample(brdf, rng, wo, N, wi, &pdf); - sum += R; - sum_sqr += R*R; + CHECK(eq_eps(R, 0.7, 1.e-6), 1); + val = ssf_bxdf_eval(brdf, wo, N, wi) * d3_dot(wi, N); + CHECK(eq_eps(val, R * pdf, 1.e-6), 1); } - E = sum/(double)NSTEPS; - V = MMAX(sum_sqr/(double)NSTEPS - E*E, 0); - SE = sqrt(V/(double)NSTEPS); - CHECK(eq_eps(E, 0.7, SE), 1); CHECK(ssf_bxdf_ref_put(brdf), RES_OK); CHECK(ssf_bxdf_ref_put(dummy), RES_OK); diff --git a/src/test_ssf_specular_reflection.c b/src/test_ssf_specular_reflection.c @@ -30,7 +30,7 @@ main(int argc, char** argv) double wo[3], wi[3]; double N[3]; double pdf; - double R; + double R; /* Directional reflectance */ size_t i; (void)argc, (void)argv; @@ -52,13 +52,13 @@ main(int argc, char** argv) d3_normalize(wo, d3(wo, 1.0, 1.0, 0.0)); R = ssf_bxdf_sample(brdf, rng, wo, N, wi, &pdf); CHECK(eq_eps(R, ssf_fresnel_eval(fresnel, d3_dot(N, wi)), 1.e-6), 1); - CHECK(pdf, 1); + CHECK(IS_INF(pdf), 1); d3_normalize(wo, d3(wo, 1.0, 1.0, 0.0)); CHECK(ssf_specular_reflection_setup(brdf, fresnel), RES_OK); R = ssf_bxdf_sample(brdf, rng, wo, N, wi, &pdf); CHECK(eq_eps(R, ssf_fresnel_eval(fresnel, d3_dot(N, wi)), 1.e-6), 1); - CHECK(pdf, 1); + CHECK(IS_INF(pdf), 1); CHECK(d3_eq_eps(d3(wo, -wo[0], wo[1], 0.0), wi, 1.e-6), 1); CHECK(ssf_bxdf_eval(brdf, wo, N, wi), 0.0); @@ -67,19 +67,19 @@ main(int argc, char** argv) d3(wo, 0.0, 1.0, 0.0); R = ssf_bxdf_sample(brdf, rng, wo, N, wi, &pdf); CHECK(eq_eps(R, ssf_fresnel_eval(fresnel, d3_dot(N, wi)), 1.e-6), 1); - CHECK(pdf, 1); + CHECK(IS_INF(pdf), 1); CHECK(d3_eq_eps(d3(wo, 0.0, 1.0, 0.0), wi, 1.e-6), 1); d3_normalize(wo, d3(wo, -1.0, 1.0, 0.0)); R = ssf_bxdf_sample(brdf, rng, wo, N, wi, &pdf); CHECK(eq_eps(R, ssf_fresnel_eval(fresnel, d3_dot(N, wi)), 1.e-6), 1); - CHECK(pdf, 1); + CHECK(IS_INF(pdf), 1); CHECK(d3_eq_eps(d3(wo, -wo[0], wo[1], 0.0), wi, 1.e-6), 1); d3(wo, 0.0, -1.0, 0.0); R = ssf_bxdf_sample(brdf, rng, wo, N, wi, &pdf); CHECK(eq_eps(R, 0, 1.e-6), 1); - CHECK(pdf, 1); + CHECK(IS_INF(pdf), 1); CHECK(d3_eq_eps(d3(wo, 0.0, -1.0, 0.0), wi, 1.e-6), 1); d3(wo, 1.0, 0.0, 0.0);