commit 10753a1d0273347d724a231060fa3737fb3c8893
parent 069846d48c0a19086eea3953008e9a1fa6797682
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 2 Mar 2017 11:48:22 +0100
Handle the total internal reflection for the thin specular dielectric BxDF
Diffstat:
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/ssf_thin_specular_dielectric.c b/src/ssf_thin_specular_dielectric.c
@@ -68,20 +68,21 @@ thin_specular_dielectric_sample
double tau, tau_sqr;
ASSERT(bxdf && rng && wi && N && wo);
ASSERT(d3_is_normalized(wo) && d3_is_normalized(N));
+ ASSERT(d3_dot(wo, N) > -1.e-6);
(void)rng;
eta = bsdf->eta_i / bsdf->eta_t;
- if(!refract(wt, wo, N, eta)) {
- d3_splat(wi, 0); /* TODO handle this case */
- return 0;
+ if(!refract(wt, wo, N, eta)) { /* Total internal reflection */
+ reflect(wi, wo, N);
+ return 1;
}
fresnel = bsdf->fresnel;
- cos_wo_N = d3_dot(wo, N);
+ cos_wo_N = MMAX(0.0, d3_dot(wo, N));
SSF(fresnel_dielectric_dielectric_setup(fresnel, bsdf->eta_i, bsdf->eta_t));
rho1 = ssf_fresnel_eval(fresnel, cos_wo_N);
- cos_wt_N = d3_dot(wt, d3_minus(tmp, N));
+ cos_wt_N = MMAX(0.0, d3_dot(wt, d3_minus(tmp, N)));
SSF(fresnel_dielectric_dielectric_setup(fresnel, bsdf->eta_t, bsdf->eta_i));
rho2 = ssf_fresnel_eval(fresnel, cos_wt_N);
diff --git a/src/test_ssf_thin_specular_dielectric.c b/src/test_ssf_thin_specular_dielectric.c
@@ -101,6 +101,14 @@ main(int argc, char** argv)
CHECK(IS_INF(pdf), 1);
CHECK(d3_eq_eps(wi, d3(tmp, -wo[0], wo[1], 0), 1.e-6), 1);
+ /* Check total internal reflection, i.e. no transmission */
+ d3_normalize(wo, d3(wo, 1, 0.0000001, 0));
+ /*CHECK(ssf_thin_specular_dielectric_setup(bsdf, 0, 1.4, 1.0, 1), RES_OK);*/
+ R = ssf_bxdf_sample(bsdf, rng, wo, N, wi, &pdf);
+ NCHECK(R, 0);
+ CHECK(IS_INF(pdf), 1);
+ CHECK(d3_eq_eps(wi, d3(tmp, -wo[0], wo[1], 0), 1.e-6), 1);
+
wo[0] = ssp_rng_uniform_double(rng, -1, 1);
wo[1] = ssp_rng_uniform_double(rng, -1, 1);
wo[2] = ssp_rng_uniform_double(rng, -1, 1);