star-sf

Set of surface and volume scattering functions
git clone git://git.meso-star.fr/star-sf.git
Log | Files | Refs | README | LICENSE

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