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 dd5d6f8b17cb798d4808f4248d4aaf0b9a5fddda
parent 754fdf3dbffa3fb0736c688edadf1dde89a4b78d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 23 Jul 2018 14:14:42 +0200

Test the dielectric/dielectric specular BSDF

Diffstat:
Mcmake/CMakeLists.txt | 1+
Asrc/test_ssf_specular_dielectric_dielectric_reflection.c | 138+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 139 insertions(+), 0 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -119,6 +119,7 @@ if(NOT NO_TEST) new_test(test_ssf_phase) new_test(test_ssf_phase_hg) new_test(test_ssf_phase_rayleigh) + new_test(test_ssf_specular_dielectric_dielectric_reflection) new_test(test_ssf_specular_reflection) new_test(test_ssf_thin_specular_dielectric) diff --git a/src/test_ssf_specular_dielectric_dielectric_reflection.c b/src/test_ssf_specular_dielectric_dielectric_reflection.c @@ -0,0 +1,138 @@ +/* Copyright (C) |Meso|Star> 2016-2018 (contact@meso-star.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * ALOng with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "ssf.h" +#include "ssf_optics.h" +#include "test_ssf_utils.h" + +#include <rsys/double3.h> + +int +main(int argc, char** argv) +{ + const size_t NSTEPS = 10000; + struct mem_allocator allocator; + struct ssp_rng* rng; + struct ssf_bsdf* bsdf; + struct ssf_bsdf* dummy; + const double eta_i = 1.00027; + const double eta_t = 1.5; + const double eta = eta_i/eta_t; + double N[3]; + double wo[3]; + double wi[3]; + double tmp[3]; + double R; + double pdf; + double sum_t, sum_t2, t; + double sum_r, sum_r2, r; + size_t i; + int type; + (void)argc, (void)argv; + + mem_init_proxy_allocator(&allocator, &mem_default_allocator); + CHK(ssp_rng_create(&allocator, &ssp_rng_mt19937_64, &rng) == RES_OK); + CHK(ssf_bsdf_create(&allocator, + &ssf_specular_dielectric_dielectric_interface, &bsdf) == RES_OK); + CHK(ssf_bsdf_create(&allocator, &bsdf_dummy, &dummy) == RES_OK); + + #define SETUP ssf_specular_dielectric_dielectric_interface_setup + CHK(SETUP(NULL, 0, 0) == RES_BAD_ARG); + CHK(SETUP(bsdf, 0, 0) == RES_BAD_ARG); + CHK(SETUP(NULL, 1, 0) == RES_BAD_ARG); + CHK(SETUP(bsdf, 1, 0) == RES_BAD_ARG); + CHK(SETUP(NULL, 0, 1) == RES_BAD_ARG); + CHK(SETUP(bsdf, 0, 1) == RES_BAD_ARG); + CHK(SETUP(NULL, 1, 1) == RES_BAD_ARG); + CHK(SETUP(bsdf, 1, 1) == RES_OK); + CHK(SETUP(dummy, 1, 1) == RES_BAD_ARG); + CHK(SETUP(bsdf, 1.00027, 1.5) == RES_OK); + #undef SETUP + + d3(N, 0, 1, 0); + + /* Test transmission */ + d3(wo, 0, 1, 0); + R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, &pdf); + CHK(R != 0); + CHK(IS_INF(pdf)); + CHK(d3_eq_eps(wi, d3(tmp,0,-1,0), 1.e-6)); + CHK(type == (SSF_SPECULAR | SSF_TRANSMISSION)); + + /* Test reflection */ + d3(wo, 1, 0, 0); + R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, &pdf); + CHK(R != 0); + CHK(IS_INF(pdf)); + CHK(d3_eq_eps(wi, d3(tmp,-1,0,0), 1.e-6)); + CHK(type == (SSF_SPECULAR | SSF_REFLECTION)); + + d3_normalize(wo, d3(wo, 1, 0.0000001, 0)); + R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, &pdf); + CHK(R == 1); + CHK(IS_INF(pdf)); + CHK(d3_eq_eps(wi, d3(tmp, -wo[0], wo[1], 0), 1.e-6) == 1); + CHK(type == (SSF_SPECULAR | SSF_REFLECTION)); + + pdf = 0, type = 0; + CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, NULL, &pdf) == R); + CHK(IS_INF(pdf)); + CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, NULL) == R); + CHK(type == (SSF_SPECULAR | SSF_REFLECTION)); + CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, NULL, NULL) == R); + + /* Check energy conservation */ + sum_t = sum_t2 = 0; + sum_r = sum_r2 = 0; + FOR_EACH(i, 0, NSTEPS) { + ssp_ran_hemisphere_cos(rng, wo, N, NULL); + R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, NULL); + if(type & SSF_TRANSMISSION) { + sum_t += R; + sum_t2 += R*R; + } else { + sum_r += R; + sum_r2 += R*R; + } + } + + t = sum_t / (double)NSTEPS; + r = sum_r / (double)NSTEPS; + CHK(t > 0); + CHK(r > 0); + CHK(eq_eps(t + r, 1, 1.e-6)); + + FOR_EACH(i, 0, NSTEPS) { + d3_normalize(wo, d3(wo,1,1,0)); + R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, &pdf); + CHK(R != 0); + CHK(type & SSF_SPECULAR); + CHK(IS_INF(pdf)); + if(d3_eq_eps(wi, refract(tmp, wo, N, eta), 1.e-6)) { + CHK(type & SSF_TRANSMISSION); + } else { + CHK(d3_eq_eps(wi, reflect(tmp, wo, N), 1.e-6)); + CHK(type & SSF_REFLECTION); + } + CHK(ssf_bsdf_pdf(bsdf, wo, N, wi) == 0); + CHK(ssf_bsdf_eval(bsdf, wo, N, wi) == 0); + } + + CHK(ssp_rng_ref_put(rng) == RES_OK); + CHK(ssf_bsdf_ref_put(bsdf) == RES_OK); + CHK(ssf_bsdf_ref_put(dummy) == RES_OK); + + return 0; +}