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 36dceabd5c342b6e83fac99ef8077a0cbdfb54c6
parent 9b919713346e6a2127253bbcb398e32c221b9d72
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 26 Sep 2016 10:43:37 +0200

Test the microfacet BRDF

Diffstat:
Mcmake/CMakeLists.txt | 1+
Asrc/test_ssf_microfacet_reflection.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -103,6 +103,7 @@ if(NOT NO_TEST) new_test(test_ssf_fresnel_dielectric_dielectric) new_test(test_ssf_fresnel_no_op) new_test(test_ssf_lambertian_reflection) + new_test(test_ssf_microfacet_reflection) new_test(test_ssf_specular_reflection) endif() diff --git a/src/test_ssf_microfacet_reflection.c b/src/test_ssf_microfacet_reflection.c @@ -0,0 +1,94 @@ +/* Copyright (C) |Meso|Star> 2016 (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 "test_ssf_utils.h" + +#include <rsys/double3.h> + +int +main(int argc, char** argv) +{ + const size_t NSTEPS = 100000; + struct mem_allocator allocator; + struct ssf_bxdf* bxdf; + struct ssf_bxdf* dummy; + struct ssf_fresnel* F; + struct ssf_microfacet_distribution* D; + double wo[3], wi[3]; + double N[3]; + double pdf; + double sum, sum_sqr; + double E, V, SE; + size_t i; + (void)argc, (void)argv; + + mem_init_proxy_allocator(&allocator, &mem_default_allocator); + CHECK(ssf_bxdf_create(&allocator, &ssf_microfacet_reflection, &bxdf), RES_OK); + CHECK(ssf_bxdf_create(&allocator, &bxdf_dummy, &dummy), RES_OK); + CHECK(ssf_fresnel_create + (&allocator, &ssf_fresnel_dielectric_dielectric, &F), RES_OK); + CHECK(ssf_microfacet_distribution_create + (&allocator, &ssf_beckmann_distribution, &D), RES_OK); + + CHECK(ssf_beckmann_distribution_setup(D, 0.7), RES_OK); + + CHECK(ssf_fresnel_dielectric_dielectric_setup(F, 0.7, 1.3), RES_OK); + + CHECK(ssf_microfacet_reflection_setup(NULL, -1, NULL, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, -1, NULL, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, 0.123, NULL, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, 0.123, NULL, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, -1, F, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, -1, F, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, 0.123, F, NULL), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, 0.123, F, NULL), RES_BAD_ARG); + + CHECK(ssf_microfacet_reflection_setup(NULL, -1, NULL, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, -1, NULL, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, 0.123, NULL, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, 0.123, NULL, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, -1, F, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, -1, F, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(NULL, 0.123, F, D), RES_BAD_ARG); + CHECK(ssf_microfacet_reflection_setup(bxdf, 0.123, F, D), RES_OK); + + /* Numerically evaluate rho */ + d3(N, 0, 1, 0); + d3_normalize(wo, d3(wo, rand_canonic(), rand_canonic(), rand_canonic())); + sum = sum_sqr = 0; + FOR_EACH(i, 0, NSTEPS) { + const double u = rand_canonic(); + const double v = rand_canonic(); + const double R = ssf_bxdf_sample(bxdf, u, v, wo, N, wi, &pdf); + const double weight = R * d3_dot(wi, N) / pdf; + sum += weight; + sum_sqr += weight*weight; + } + E = sum / (double)NSTEPS; + V = sum_sqr / (double)NSTEPS - E*E; + SE = sqrt(V/(double)NSTEPS); + CHECK(eq_eps(E, ssf_bxdf_rho(bxdf, wo, N), SE), 1); + + CHECK(ssf_bxdf_ref_put(bxdf), RES_OK); + CHECK(ssf_bxdf_ref_put(dummy), RES_OK); + CHECK(ssf_fresnel_ref_put(F), RES_OK); + CHECK(ssf_microfacet_distribution_ref_put(D), RES_OK); + + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHECK(mem_allocated_size(), 0); + return 0; +}