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 }