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_distribution.c (6131B)


      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 static int ufacet_is_init = 0;
     22 
     23 struct ALIGN(64) ufacet {
     24   uint32_t id;
     25   struct ssp_rng* rng;
     26   double wh[3];
     27   double N[3];
     28   double pdf;
     29   double value;
     30 };
     31 
     32 static res_T
     33 ufacet_init(struct mem_allocator* allocator, void* distrib)
     34 {
     35   CHK(allocator != NULL);
     36   CHK(distrib != NULL);
     37   CHK(IS_ALIGNED(distrib, 64) == 1);
     38   ((struct ufacet*)distrib)->id = 0xDECAFBAD;
     39   ufacet_is_init = 1;
     40   return RES_OK;
     41 }
     42 
     43 static void
     44 ufacet_release(void* distrib)
     45 {
     46   CHK(distrib != NULL);
     47   CHK(((struct ufacet*)distrib)->id == 0xDECAFBAD);
     48   ufacet_is_init = 0;
     49 }
     50 
     51 static void
     52 ufacet_sample
     53   (void* distrib,
     54    struct ssp_rng* rng,
     55    const double N[3],
     56    double wh[3],
     57    double* pdf)
     58 {
     59   struct ufacet* ufacet = distrib;
     60   CHK(ufacet != NULL);
     61   CHK(N != NULL);
     62   CHK(wh != NULL);
     63   CHK(ufacet->rng == rng);
     64   CHK(d3_eq(ufacet->N, N) == 1);
     65   d3_normalize(wh, d3(wh, 1.0, 2.0, 3.0));
     66   if(pdf) *pdf = ufacet->pdf;
     67 }
     68 
     69 static double
     70 ufacet_eval
     71   (void* distrib,
     72    const double N[3],
     73    const double wh[3])
     74 {
     75   struct ufacet* ufacet = distrib;
     76   CHK(distrib != NULL);
     77   CHK(N != NULL);
     78   CHK(wh != NULL);
     79   CHK(d3_eq(ufacet->wh, wh) == 1);
     80   CHK(d3_eq(ufacet->N, N) == 1);
     81   return ufacet->value;
     82 }
     83 
     84 static double
     85 ufacet_pdf
     86   (void* distrib,
     87    const double N[3],
     88    const double wh[3])
     89 {
     90   struct ufacet* ufacet = distrib;
     91   CHK(N != NULL);
     92   CHK(wh != NULL);
     93   CHK(d3_eq(ufacet->wh, wh) == 1);
     94   CHK(d3_eq(ufacet->N, N) == 1);
     95   return ufacet->pdf;
     96 }
     97 
     98 int
     99 main(int argc, char** argv)
    100 {
    101   struct mem_allocator allocator;
    102   struct ufacet* data;
    103   struct ssf_microfacet_distribution_type type =
    104     SSF_MICROFACET_DISTRIBUTION_TYPE_NULL;
    105   struct ssf_microfacet_distribution_type type2 = microfacet_dummy;
    106   struct ssf_microfacet_distribution* distrib;
    107   struct ssp_rng* rng;
    108   double N[3], wh[3], pdf;
    109   (void)argc, (void)argv;
    110 
    111   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
    112   CHK(ssp_rng_create(&allocator, SSP_RNG_THREEFRY, &rng) == RES_OK);
    113 
    114   type.init = ufacet_init;
    115   type.release = ufacet_release;
    116   type.sample = ufacet_sample;
    117   type.eval = ufacet_eval;
    118   type.pdf = ufacet_pdf;
    119   type.sizeof_distribution = sizeof(struct ufacet);
    120   type.alignof_distribution = ALIGNOF(struct ufacet);
    121 
    122   #define CREATE ssf_microfacet_distribution_create
    123   CHK(CREATE(NULL, NULL, NULL) == RES_BAD_ARG);
    124   CHK(CREATE(&allocator, NULL, NULL) == RES_BAD_ARG);
    125   CHK(CREATE(NULL, &type, NULL) == RES_BAD_ARG);
    126   CHK(CREATE(&allocator, &type, NULL) == RES_BAD_ARG);
    127   CHK(CREATE(NULL, NULL, &distrib) == RES_BAD_ARG);
    128   CHK(CREATE(&allocator, NULL, &distrib) == RES_BAD_ARG);
    129 
    130   CHK(ufacet_is_init == 0);
    131   CHK(CREATE(NULL, &type, &distrib) == RES_OK);
    132   CHK(ufacet_is_init == 1);
    133 
    134   CHK(ssf_microfacet_distribution_ref_get(NULL) == RES_BAD_ARG);
    135   CHK(ssf_microfacet_distribution_ref_get(distrib) == RES_OK);
    136   CHK(ssf_microfacet_distribution_ref_put(NULL) == RES_BAD_ARG);
    137   CHK(ssf_microfacet_distribution_ref_put(distrib) == RES_OK);
    138   CHK(ufacet_is_init == 1);
    139   CHK(ssf_microfacet_distribution_ref_put(distrib) == RES_OK);
    140   CHK(ufacet_is_init == 0);
    141 
    142   CHK(CREATE(&allocator, &type, &distrib) == RES_OK);
    143   CHK(ufacet_is_init == 1);
    144   CHK(ssf_microfacet_distribution_ref_put(distrib) == RES_OK);
    145   CHK(ufacet_is_init == 0);
    146 
    147   type2.init = NULL;
    148   CHK(CREATE(&allocator, &type2, &distrib) == RES_OK);
    149   CHK(ssf_microfacet_distribution_ref_put(distrib) == RES_OK);
    150   type2.init = microfacet_dummy.init;
    151   type2.release = NULL;
    152   CHK(CREATE(&allocator, &type2, &distrib) == RES_OK);
    153   CHK(ssf_microfacet_distribution_ref_put(distrib) == RES_OK);
    154 
    155   type.sample = NULL;
    156   CHK(CREATE(&allocator, &type, &distrib) == RES_BAD_ARG);
    157   type.sample = ufacet_sample;
    158   type.eval = NULL;
    159   CHK(CREATE(&allocator, &type, &distrib) == RES_BAD_ARG);
    160   type.eval = ufacet_eval;
    161   type.pdf = NULL;
    162   CHK(CREATE(&allocator, &type, &distrib) == RES_BAD_ARG);
    163   type.pdf = ufacet_pdf;
    164   type.alignof_distribution = 0;
    165   CHK(CREATE(&allocator, &type, &distrib) == RES_BAD_ARG);
    166   type.alignof_distribution = ALIGNOF(struct ufacet);
    167   CHK(CREATE(&allocator, &type, &distrib) == RES_OK);
    168   CHK(ufacet_is_init == 1);
    169   #undef CREATE
    170 
    171   CHK(ssf_microfacet_distribution_get_data(NULL, NULL) == RES_BAD_ARG);
    172   CHK(ssf_microfacet_distribution_get_data(distrib, NULL) == RES_BAD_ARG);
    173   CHK(ssf_microfacet_distribution_get_data(NULL, (void**)&data) == RES_BAD_ARG);
    174   CHK(ssf_microfacet_distribution_get_data(distrib, (void**)&data) == RES_OK);
    175   CHK(data->id == 0xDECAFBAD);
    176 
    177   d3(N, 0.0, 1.0, 0.0);
    178   d3_set(data->N, N);
    179   d3_normalize(data->wh, d3(data->wh, 1, 2, 3));
    180   data->rng = rng;
    181   data->pdf = 0.1234;
    182   data->value = 0.43;
    183 
    184   ssf_microfacet_distribution_sample(distrib, rng, N, wh, NULL);
    185   ssf_microfacet_distribution_sample(distrib, rng, N, wh, &pdf);
    186   CHK(d3_eq(wh, data->wh) == 1);
    187   CHK(pdf == data->pdf);
    188   ssf_microfacet_distribution_sample(distrib, rng, N, wh, &pdf);
    189   CHK(d3_eq(wh, data->wh) == 1);
    190   CHK(pdf == data->pdf);
    191 
    192   CHK(ssf_microfacet_distribution_eval(distrib, N, wh) == data->value);
    193   CHK(ssf_microfacet_distribution_pdf(distrib, N, wh) == data->pdf);
    194 
    195   CHK(ssf_microfacet_distribution_ref_put(distrib) == RES_OK);
    196   CHK(ufacet_is_init == 0);
    197 
    198   CHK(ssp_rng_ref_put(rng) == RES_OK);
    199 
    200   check_memory_allocator(&allocator);
    201   mem_shutdown_proxy_allocator(&allocator);
    202   CHK(mem_allocated_size() == 0);
    203   return 0;
    204 }