test_ssf_specular_reflection.c (4261B)
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 21 int 22 main(int argc, char** argv) 23 { 24 const size_t NSTEPS = 100000; 25 struct mem_allocator allocator; 26 struct ssp_rng* rng; 27 struct ssf_bsdf* brdf; 28 struct ssf_bsdf* dummy; 29 struct ssf_fresnel* fresnel; 30 double wo[3], wi[3]; 31 double N[3]; 32 double pdf; 33 double R; /* Directional reflectance */ 34 size_t i; 35 int type; 36 (void)argc, (void)argv; 37 38 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 39 CHK(ssp_rng_create(&allocator, SSP_RNG_THREEFRY, &rng) == RES_OK); 40 CHK(ssf_bsdf_create(&allocator, &ssf_specular_reflection, &brdf) == RES_OK); 41 CHK(ssf_bsdf_create(&allocator, &bsdf_dummy, &dummy) == RES_OK); 42 CHK(ssf_fresnel_create 43 (&allocator, &ssf_fresnel_dielectric_dielectric, &fresnel) == RES_OK); 44 CHK(ssf_fresnel_dielectric_dielectric_setup(fresnel, 0.7, 1) == RES_OK); 45 46 CHK(ssf_specular_reflection_setup(NULL, NULL) == RES_BAD_ARG); 47 CHK(ssf_specular_reflection_setup(brdf, NULL) == RES_BAD_ARG); 48 CHK(ssf_specular_reflection_setup(NULL, fresnel) == RES_BAD_ARG); 49 CHK(ssf_specular_reflection_setup(brdf, fresnel) == RES_OK); 50 CHK(ssf_specular_reflection_setup(dummy, fresnel) == RES_BAD_ARG); 51 52 d3(N, 0.0, 1.0, 0.0); 53 d3_normalize(wo, d3(wo, 1.0, 1.0, 0.0)); 54 R = ssf_bsdf_sample(brdf, rng, wo, N, wi, &type, &pdf); 55 CHK(eq_eps(R, ssf_fresnel_eval(fresnel, d3_dot(N, wi)), 1.e-6) == 1); 56 CHK(IS_INF(pdf) == 1); 57 CHK(type == (SSF_SPECULAR|SSF_REFLECTION)); 58 59 pdf = 0, type = 0; 60 CHK(ssf_bsdf_sample(brdf, rng, wo, N, wi, NULL, &pdf) == R); 61 CHK(IS_INF(pdf)); 62 CHK(ssf_bsdf_sample(brdf, rng, wo, N, wi, &type, NULL) == R); 63 CHK(type == (SSF_SPECULAR|SSF_REFLECTION)); 64 CHK(ssf_bsdf_sample(brdf, rng, wo, N, wi, NULL, NULL) == R); 65 66 d3_normalize(wo, d3(wo, 1.0, 1.0, 0.0)); 67 CHK(ssf_specular_reflection_setup(brdf, fresnel) == RES_OK); 68 R = ssf_bsdf_sample(brdf, rng, wo, N, wi, &type, &pdf); 69 CHK(eq_eps(R, ssf_fresnel_eval(fresnel, d3_dot(N, wi)), 1.e-6) == 1); 70 CHK(IS_INF(pdf) == 1); 71 CHK(d3_eq_eps(d3(wo, -wo[0], wo[1], 0.0), wi, 1.e-6) == 1); 72 CHK(type == (SSF_SPECULAR|SSF_REFLECTION)); 73 74 CHK(ssf_bsdf_eval(brdf, wo, N, wi) == 0.0); 75 CHK(ssf_bsdf_pdf(brdf, wo, N, wi) == 0.0); 76 77 d3(wo, 0.0, 1.0, 0.0); 78 R = ssf_bsdf_sample(brdf, rng, wo, N, wi, &type, &pdf); 79 CHK(eq_eps(R, ssf_fresnel_eval(fresnel, d3_dot(N, wi)), 1.e-6) == 1); 80 CHK(IS_INF(pdf) == 1); 81 CHK(d3_eq_eps(d3(wo, 0.0, 1.0, 0.0), wi, 1.e-6) == 1); 82 CHK(type == (SSF_SPECULAR|SSF_REFLECTION)); 83 84 d3_normalize(wo, d3(wo, -1.0, 1.0, 0.0)); 85 R = ssf_bsdf_sample(brdf, rng, wo, N, wi, &type, &pdf); 86 CHK(eq_eps(R, ssf_fresnel_eval(fresnel, d3_dot(N, wi)), 1.e-6) == 1); 87 CHK(IS_INF(pdf) == 1); 88 CHK(d3_eq_eps(d3(wo, -wo[0], wo[1], 0.0), wi, 1.e-6) == 1); 89 CHK(type == (SSF_SPECULAR|SSF_REFLECTION)); 90 91 wo[0] = ssp_rng_uniform_double(rng, -1, 1); 92 wo[1] = ssp_rng_uniform_double(rng, 0, 1); 93 wo[2] = ssp_rng_uniform_double(rng, -1, 1); 94 d3_normalize(wo, wo); 95 R = ssf_bsdf_sample(brdf, rng, wo, N, wi, &type, &pdf); 96 CHK(type == (SSF_SPECULAR|SSF_REFLECTION)); 97 98 FOR_EACH(i, 0, NSTEPS) { 99 CHK(eq_eps(ssf_bsdf_sample(brdf, rng, wo, N, wi, &type, &pdf), R, 1.e-6)); 100 CHK(type == (SSF_SPECULAR|SSF_REFLECTION)); 101 } 102 103 CHK(ssf_bsdf_ref_put(brdf) == RES_OK); 104 CHK(ssf_bsdf_ref_put(dummy) == RES_OK); 105 CHK(ssf_fresnel_ref_put(fresnel) == RES_OK); 106 CHK(ssp_rng_ref_put(rng) == RES_OK); 107 108 check_memory_allocator(&allocator); 109 mem_shutdown_proxy_allocator(&allocator); 110 CHK(mem_allocated_size() == 0); 111 return 0; 112 }