test_ssf_microfacet_reflection.c (4557B)
1 /* Copyright (C) 2016-2018, 2021-2025 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "ssf.h" 17 #include "test_ssf_utils.h" 18 19 #include <rsys/double3.h> 20 #include <star/ssp.h> 21 22 int 23 main(int argc, char** argv) 24 { 25 struct mem_allocator allocator; 26 struct ssf_bsdf* bsdf; 27 struct ssf_bsdf* dummy; 28 struct ssf_fresnel* F; 29 struct ssf_microfacet_distribution* D; 30 struct ssp_rng* rng; 31 double N[3]; 32 double wo[3]; 33 double wi[3]; 34 double pdf; 35 double R; 36 size_t i, NSTEPS=10000; 37 int type; 38 (void)argc, (void)argv; 39 40 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 41 CHK(ssp_rng_create(&allocator, SSP_RNG_THREEFRY, &rng) == RES_OK); 42 CHK(ssf_bsdf_create(&allocator, &ssf_microfacet2_reflection, &bsdf) == RES_OK); 43 CHK(ssf_bsdf_create(&allocator, &bsdf_dummy, &dummy) == RES_OK); 44 CHK(ssf_fresnel_create(&allocator, &ssf_fresnel_no_op, &F) == RES_OK); 45 CHK(ssf_microfacet_distribution_create 46 (&allocator, &ssf_beckmann_distribution, &D) == RES_OK); 47 48 CHK(ssf_beckmann_distribution_setup(D, 0.9) == RES_OK); 49 50 CHK(ssf_microfacet_reflection_setup(NULL, NULL, NULL) == RES_BAD_ARG); 51 CHK(ssf_microfacet_reflection_setup(bsdf, NULL, NULL) == RES_BAD_ARG); 52 CHK(ssf_microfacet_reflection_setup(NULL, F, NULL) == RES_BAD_ARG); 53 CHK(ssf_microfacet_reflection_setup(bsdf, F, NULL) == RES_BAD_ARG); 54 CHK(ssf_microfacet_reflection_setup(NULL, NULL, D) == RES_BAD_ARG); 55 CHK(ssf_microfacet_reflection_setup(bsdf, NULL, D) == RES_BAD_ARG); 56 CHK(ssf_microfacet_reflection_setup(NULL, F, D) == RES_BAD_ARG); 57 CHK(ssf_microfacet_reflection_setup(bsdf, F, D) == RES_OK); 58 59 /* Check energy conservation */ 60 ssp_ran_sphere_uniform(rng, N, NULL); 61 ssp_ran_hemisphere_cos(rng, N, wo, NULL); 62 FOR_EACH(i, 0, NSTEPS) { 63 CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, &pdf) == 1); 64 CHK(type == (SSF_GLOSSY | SSF_REFLECTION)); 65 CHK(IS_NaN(pdf)); 66 CHK(d3_dot(wi, N) > 0); 67 68 pdf = 0, type = 0; 69 CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, NULL, &pdf) == 1); 70 CHK(IS_NaN(pdf)); 71 CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, NULL) == 1); 72 CHK(type == (SSF_GLOSSY | SSF_REFLECTION)); 73 CHK(ssf_bsdf_sample(bsdf, rng, wo, N, wi, NULL, NULL) == 1); 74 } 75 76 CHK(ssf_bsdf_ref_put(bsdf) == RES_OK); 77 CHK(ssf_bsdf_create(&allocator, &ssf_microfacet_reflection, &bsdf) == RES_OK); 78 79 CHK(ssf_microfacet_reflection_setup(NULL, NULL, NULL) == RES_BAD_ARG); 80 CHK(ssf_microfacet_reflection_setup(bsdf, NULL, NULL) == RES_BAD_ARG); 81 CHK(ssf_microfacet_reflection_setup(NULL, F, NULL) == RES_BAD_ARG); 82 CHK(ssf_microfacet_reflection_setup(bsdf, F, NULL) == RES_BAD_ARG); 83 CHK(ssf_microfacet_reflection_setup(NULL, NULL, D) == RES_BAD_ARG); 84 CHK(ssf_microfacet_reflection_setup(bsdf, NULL, D) == RES_BAD_ARG); 85 CHK(ssf_microfacet_reflection_setup(NULL, F, D) == RES_BAD_ARG); 86 CHK(ssf_microfacet_reflection_setup(bsdf, F, D) == RES_OK); 87 88 FOR_EACH(i, 0, NSTEPS) { 89 R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, &pdf); 90 CHK(R == (d3_dot(wi, N) > 0 ? 1 : 0)); 91 CHK(type == (SSF_GLOSSY | SSF_REFLECTION)); 92 CHK(eq_eps(pdf, ssf_bsdf_pdf(bsdf, wo, N, wi), 1.e-6)); 93 94 pdf = 0, type = 0; 95 R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, NULL, &pdf); 96 CHK(R == (d3_dot(wi, N) > 0 ? 1 : 0)); 97 CHK(eq_eps(pdf, ssf_bsdf_pdf(bsdf, wo, N, wi), 1.e-6)); 98 R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, &type, NULL); 99 CHK(R == (d3_dot(wi, N) > 0 ? 1 : 0)); 100 CHK(type == (SSF_GLOSSY | SSF_REFLECTION)); 101 R = ssf_bsdf_sample(bsdf, rng, wo, N, wi, NULL, NULL); 102 CHK(R == (d3_dot(wi, N) > 0 ? 1 : 0)); 103 } 104 105 CHK(ssf_bsdf_ref_put(bsdf) == RES_OK); 106 CHK(ssf_bsdf_ref_put(dummy) == RES_OK); 107 CHK(ssf_fresnel_ref_put(F) == RES_OK); 108 CHK(ssf_microfacet_distribution_ref_put(D) == RES_OK); 109 CHK(ssp_rng_ref_put(rng) == RES_OK); 110 111 check_memory_allocator(&allocator); 112 mem_shutdown_proxy_allocator(&allocator); 113 CHK(mem_allocated_size() == 0); 114 return 0; 115 } 116