ssf.h (25685B)
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 #ifndef SSF_H 17 #define SSF_H 18 19 #include <rsys/rsys.h> 20 #include <float.h> 21 22 /* Library symbol management */ 23 #if defined(SSF_SHARED_BUILD) /* Build shared library */ 24 #define SSF_API extern EXPORT_SYM 25 #elif defined(SSF_STATIC_BUILD) /* Use/build static library */ 26 #define SSF_API extern LOCAL_SYM 27 #else /* Use shared library */ 28 #define SSF_API extern IMPORT_SYM 29 #endif 30 31 /* Helper macro that asserts if the invocation of the ssf function `Func' 32 * returns an error. */ 33 #ifndef NDEBUG 34 #define SSF(Func) ASSERT(ssf_##Func == RES_OK) 35 #else 36 #define SSF(Func) ssf_##Func 37 #endif 38 39 /* Max value of the exponent parameter in the Blinn microfacet distribution */ 40 #define SSF_BLINN_DISTRIBUTION_MAX_EXPONENT 10000.0 41 42 /* Forward declaration */ 43 struct mem_allocator; 44 struct ssp_rng; 45 46 /* Opaque data types */ 47 struct ssf_bsdf; /* Bidirectional Scattering Distribution Function */ 48 struct ssf_fresnel; /* Equation of the Fresnel term */ 49 struct ssf_microfacet_distribution; 50 struct ssf_phase; /* Phase function */ 51 52 enum ssf_bxdf_flag { 53 SSF_REFLECTION = BIT(0), 54 SSF_TRANSMISSION = BIT(1), 55 SSF_SPECULAR = BIT(2), 56 SSF_DIFFUSE = BIT(3), 57 SSF_GLOSSY = BIT(4) 58 }; 59 60 enum ssf_simd { 61 SSF_SIMD_NONE, 62 SSF_SIMD_128, 63 SSF_SIMD_256 64 }; 65 66 /* Generic BSDF type descriptor. Note that by convention the outgoing direction 67 * `wo' and the incoming direction `wi' point outward the surface. Furthermore, 68 * `wo' and the normal N must point on the same side of the surface. As a 69 * consequence the reflected or refracted direction `wi' must point on the same 70 * side or on the opposite side of `N', respectively. */ 71 struct ssf_bsdf_type { 72 res_T (*init)(struct mem_allocator* allocator, void* bsdf); /* Can be NULL */ 73 void (*release)(void* bsdf); /* Can be NULL */ 74 75 /* Sample a direction `wi' wrt `wo' whose pdf is BSDF(wo, wi) |wi.n|. Return 76 * the value of BSDF(wo, wi) */ 77 double 78 (*sample) 79 (void* bsdf, 80 struct ssp_rng* rng, /* Random number generator */ 81 const double wo[3], /* Normalized outgoing direction */ 82 const double N[3], /* Normalized surface normal */ 83 double wi[3], /* Sampled normalized incoming direction */ 84 int* type, /* Sampled component. Combination of ssf_bxdf_flag. Can be NULL */ 85 double* pdf); /* PDF to sample wi wrt wo. Can be NULL */ 86 87 /* Evaluate the BxDF wrt `wo' and `wi' */ 88 double 89 (*eval) 90 (void* bsdf, 91 const double wo[3], /* Normalized outgoing direction */ 92 const double N[3], /* Normalized surface normal */ 93 const double wi[3]);/* Normalized incoming direction */ 94 95 /* Probability density function */ 96 double 97 (*pdf) 98 (void* bsdf, 99 const double wo[3], /* Normalized outgoing direction */ 100 const double N[3], /* Normalized surface normal */ 101 const double wi[3]);/* Normalized incoming direction */ 102 103 size_t sizeof_bsdf; /* In Bytes */ 104 size_t alignof_bsdf; /* In Bytes. Must be a power of 2 */ 105 }; 106 #define SSF_BSDF_TYPE_NULL__ {NULL, NULL, NULL, NULL, NULL, 0, 1} 107 static const struct ssf_bsdf_type SSF_BXDF_TYPE_NULL = SSF_BSDF_TYPE_NULL__; 108 109 /* Generic Fresnel term descriptor */ 110 struct ssf_fresnel_type { 111 res_T (*init)(struct mem_allocator* allocator, void* fresnel); /* Can be NULL */ 112 void (*release)(void* bxdf); /* Can be NULL */ 113 114 double 115 (*eval) 116 (void* fresnel, 117 const double cos_wi_N); /* Cosine between facet normal and incoming dir */ 118 119 size_t sizeof_fresnel; /* In Bytes */ 120 size_t alignof_fresnel; /* In Bytes. Must be a power of 2 */ 121 }; 122 #define SSF_FRESNEL_TYPE_NULL__ {NULL, NULL, NULL, 0, 1} 123 static const struct ssf_fresnel_type SSF_FRESNEL_TYPE_NULL = 124 SSF_FRESNEL_TYPE_NULL__; 125 126 /* Generic descriptor of a microfacet distribution */ 127 struct ssf_microfacet_distribution_type { 128 res_T (*init)(struct mem_allocator* allocator, void* distrib); /* Can be NULL */ 129 void (*release)(void* distrib); /* Can be NULL */ 130 131 void 132 (*sample) 133 (void* distrib, 134 struct ssp_rng* rng, /* Random number generator */ 135 const double N[3], /* Normalized Z-direction of the distribution */ 136 double wh[3], /* Sampled normalized half vector */ 137 double* pdf); /* PDF to sample wh. Can be NULL */ 138 139 double 140 (*eval) 141 (void* distrib, 142 const double N[3], /* Normalized Z-direction of the distribution */ 143 const double wh[3]); /* Normalized half vector */ 144 145 double 146 (*pdf) 147 (void* distrib, 148 const double N[3], /* Normalized Z-direction of the distribution */ 149 const double wh[3]); /* Normalized half vector */ 150 151 size_t sizeof_distribution; /* In Bytes */ 152 size_t alignof_distribution; /* In Bytes. Must be a Power of 2 */ 153 }; 154 #define SSF_MICROFACET_DISTRIBUTION_TYPE_NULL__ \ 155 {NULL, NULL, NULL, NULL, NULL, 0, 1} 156 static const struct ssf_microfacet_distribution_type 157 SSF_MICROFACET_DISTRIBUTION_TYPE_NULL = SSF_MICROFACET_DISTRIBUTION_TYPE_NULL__; 158 159 /* Generic phase function type descriptor. Note that by convention the outgoing 160 * direction `wo' and the incoming direction `wi' point *OUTWARD* the scattering 161 * point. The scattering angle is thus acos(-wo.wi) */ 162 struct ssf_phase_type { 163 res_T (*init)(struct mem_allocator* allocator, void* phase); /*Can be NULL*/ 164 void (*release)(void* phase); /* Can be NULL */ 165 166 /* Sample a direction `wi' wrt `wo'. */ 167 void 168 (*sample) 169 (void* phase, 170 struct ssp_rng* rng, /* Random number generator */ 171 const double wo[3], /* Normalized outgoing direction */ 172 double wi[3], /* Sampled normalized incoming direction */ 173 double* pdf); /* PDF to sample wi wrt wo. Can be NULL */ 174 175 /* Evaluate the phase function wrt `wo' and `wi' */ 176 double 177 (*eval) 178 (void* phase, 179 const double wo[3], /* Normalized outgoing direction */ 180 const double wi[3]); /* Normalized incoming direction */ 181 182 /* Probability density function */ 183 double 184 (*pdf) 185 (void* phase, 186 const double wo[3], /* Normalized outgoing direction */ 187 const double wi[3]); /* Normalized incoming direction */ 188 189 size_t sizeof_phase; /* In Bytes */ 190 size_t alignof_phase; /* In Bytes. Must be a power of 2 */ 191 }; 192 #define SSF_PHASE_TYPE_NULL__ {NULL,NULL,NULL,NULL,NULL,0,1} 193 static const struct ssf_phase_type SSF_PHASE_TYPE_NULL = SSF_PHASE_TYPE_NULL__; 194 195 struct ssf_info { 196 /* Define the supported SIMD instruction sets */ 197 char simd_128; 198 char simd_256; 199 }; 200 #define SSF_INFO_NULL__ {0,0} 201 static const struct ssf_info SSF_INFO_NULL = SSF_INFO_NULL__; 202 203 /* RDGFA phase function input arguments */ 204 struct ssf_phase_rdgfa_setup_args { 205 double wavelength; /* In nm */ 206 double fractal_dimension; /* No unit */ 207 double gyration_radius; /* In nm */ 208 209 /* Number of #intervals to use to discretize the angular domain */ 210 size_t nintervals; 211 212 enum ssf_simd simd; /* SIMD instruction sets to use */ 213 }; 214 #define SSF_PHASE_RDGFA_SETUP_ARGS_DEFAULT__ {0,0,0,1000,SSF_SIMD_NONE} 215 static const struct ssf_phase_rdgfa_setup_args 216 SSF_PHASE_RDGFA_SETUP_ARGS_DEFAULT = SSF_PHASE_RDGFA_SETUP_ARGS_DEFAULT__; 217 218 struct ssf_phase_rdgfa_desc { 219 double wavelength; /* In nm */ 220 double fractal_dimension; /* No unit */ 221 double gyration_radius; /* In nm */ 222 223 double normalization_factor; /* Normalization factor of the cumulative */ 224 size_t nintervals; /* #intervals used to discretized the cumulative */ 225 }; 226 #define SSF_PHASE_RDGFA_DESC_NULL__ {0,0,0,0,0} 227 static const struct ssf_phase_rdgfa_desc SSF_PHASE_RDGFA_DESC_NULL = 228 SSF_PHASE_RDGFA_DESC_NULL__; 229 230 struct ssf_phase_rdgfa_interval { 231 double range[2]; /* Angular range of the interval. In rad */ 232 double cumulative; /* Value of the cumulative of the interval */ 233 }; 234 #define SSF_PHASE_RDGFA_INTERVAL_NULL__ {{DBL_MAX,-DBL_MAX}, 0} 235 static const struct ssf_phase_rdgfa_interval SSF_PHASE_RDGFA_INTERVAL_NULL = 236 SSF_PHASE_RDGFA_INTERVAL_NULL__; 237 238 struct ssf_discrete_item { 239 double theta; /* In radian */ 240 double value; 241 }; 242 #define SSF_DISCRETE_ITEM_NULL__ {0,0} 243 static const struct ssf_discrete_item SSF_DISCRETE_ITEM_NULL = 244 SSF_DISCRETE_ITEM_NULL__; 245 246 /* Discrete phase function input arguments */ 247 struct ssf_discrete_setup_args { 248 void (*get_item) /* Returns a given discrete item */ 249 (const size_t iitem, 250 struct ssf_discrete_item* item, 251 void* context); 252 void* context; /* User defined data sent to `get_item' functor */ 253 size_t nitems; /* #discrete items */ 254 }; 255 #define SSF_DISCRETE_SETUP_ARGS_NULL__ {NULL,NULL,0} 256 static const struct ssf_discrete_setup_args 257 SSF_DISCRETE_SETUP_ARGS_NULL = SSF_DISCRETE_SETUP_ARGS_NULL__; 258 259 BEGIN_DECLS 260 261 /******************************************************************************* 262 * Built-in BSDFs 263 ******************************************************************************/ 264 /* Dirac distribution whose incoming direction `wi' is the reflection of the 265 * supplied direction `wo' with respect to the surface normal `N'. The 266 * directional reflectance is controlled by the Fresnel term `Fr'. 267 * fr(wo, wi) = Fr(|wi.N|) * delta(wo - Reflect(wi, N)) / |wi.N| 268 * Since it is a dirac distribution, the returned value of the `eval' and `pdf' 269 * function is always 0 while the pdf returned by `sample' function is 270 * infinity. */ 271 SSF_API const struct ssf_bsdf_type ssf_specular_reflection; 272 273 /* Reflects the same intensity in all direction independently of the incoming 274 * direction; fr(wo, wr) = R/PI */ 275 SSF_API const struct ssf_bsdf_type ssf_lambertian_reflection; 276 277 /* Glossy reflections with respect to a microfacet distribution. It is based on 278 * the Torrance Sparrow BRDF to provide a general Microfacet-based BRDF model 279 * fr(wo, wi) = Fr(|wi.wh|) * G(wo, wi) * D(wh) / (4 * |wo.N| * |wi.N|) 280 * with `wh' the half vector between `wi' and `wo', `Fr(|wi.wh|)' the Fresnel 281 * term that controls the directional reflectance, `G(wo, wi)' the geometric 282 * attenuation term that describes the masking and the shadowing of the 283 * microfacets and `D(wh)' the distribution area of the microfacets whose 284 * normal is `wh'. Note that common BRDFs based on this model ignore multiple 285 * scattering of lights into the microfacet structure and remove them with the 286 * 'G' term. As a consequence, this model does not satisfy the energy 287 * conservation property */ 288 SSF_API const struct ssf_bsdf_type ssf_microfacet_reflection; 289 290 /* Glossy reflections with respect to a microfacet distribution. In contrast to 291 * the ssp_microfacet_reflection model, this BRDF ensures, by design, the 292 * energy conservation property without requiring the normalization of the 293 * BRDF. As a counterpart, it only provides the sample function. The others 294 * functions return invalid value. However, it is well suited for Monte Carlo 295 * integrations that only need to sample a direction and to define its 296 * associated directional reflectance */ 297 SSF_API const struct ssf_bsdf_type ssf_microfacet2_reflection; 298 299 /* This BSDF consists in a model of refraction effects within a thin slab of a 300 * dielectric material, combine with a dirac distribution of the reflection at 301 * the interfaces as provided by ssf_specular_reflection. Global reflection (R), 302 * absorption (A) and transmission (T) parameters are computed from the 303 * infinite series of contributions that come from multiple refraction effects 304 * within the slab. 305 * 306 * Assuming a perfect dielectric material, the Fresnel term provided by 307 * ssf_fresnel_dielectric_dielectric is used to compute "rho", i.e. the 308 * reflected part during a single refraction event. But since real materials 309 * are not ideal dielectrics, the slab is also supposed to absorb incoming 310 * radiation. The absorption coefficient "alpha" of the material is provided 311 * by the user. */ 312 SSF_API const struct ssf_bsdf_type ssf_thin_specular_dielectric; 313 314 /* Dirac distribution whose incoming direction `wi' is either refracted or 315 * reflecter wrt N and a dielectric/dielectric fresnel term `Fr'. 316 * f_reflected(wo, wi) = Fr(|wi.N|) * delta(wo - Reflect(wi, N)) / |wi.N| 317 * f_refracted(wo, wi) = (1-Fr(|wi.N|)) * delta(wo - Refract(wi, N)) / |wi.N| 318 * Since it is a dirac distribution, the returned value of the `eval' and `pdf' 319 * function is always 0 while the pdf returned by `sample' function is 320 * infinity. */ 321 SSF_API const struct ssf_bsdf_type ssf_specular_dielectric_dielectric_interface; 322 323 /******************************************************************************* 324 * Built-in Fresnel terms 325 ******************************************************************************/ 326 /* Fresnel term is a constant; Fr = k with k in [0, 1]. */ 327 SSF_API const struct ssf_fresnel_type ssf_fresnel_constant; 328 329 /* Fresnel term for perfect reflection; Fr = 1 */ 330 SSF_API const struct ssf_fresnel_type ssf_fresnel_no_op; 331 332 /* Fresnel term between 2 dielectric mediums. 333 * Fr = 1/2 * (Rs^2 + Rp^2) 334 * with `Rs' and `Rp' the reflectance for the light polarized with its electric 335 * field perpendicular or parallel to the plane of incidence, respectively. 336 * Rs = (n1*|wi.N| - n2*|wt.N|) / (n1*|wi.N| + n2*|wt.N) 337 * Rp = (n2*|wi.N| - n1*|wt.N|) / (n2*|wi.N| + n1*|wt.N) 338 * with `n1' and `n2' the indices of refraction of the incident and transmitted 339 * media, and `wi' and `wt' the incident and transmitted direction. */ 340 SSF_API const struct ssf_fresnel_type ssf_fresnel_dielectric_dielectric; 341 342 /* Fresnel term between a dielectric and a conductor. 343 * Fr = 1/2 * (Rs^2 + Rp^2) 344 * with `Rs' and `Rp' the reflectance for the light polarized with its electric 345 * field perpendicular or parallel to the plane of incidence, respectively. 346 * Rs = (n1*|wi.N| - (n2 - i*k2)*|wt.N|) / (n1*|wi.N| + (n2 - i*k2)*|wt.N|) 347 * Rp = ((n2 - i*k2)*|wt.N| - n1*|wi.N|) / ((n2 - i*k2)*|wt.N| + n1*|wi.N|) 348 * with `n1' the index of refraction of the incident media, `n2' and `k2' the 349 * real and imaginary part of the index of refraction of the transmitted media, 350 * and `wi' and `wt' the incident and transmitted direction */ 351 SSF_API const struct ssf_fresnel_type ssf_fresnel_dielectric_conductor; 352 353 /******************************************************************************* 354 * Built-in microfacet distributions 355 ******************************************************************************/ 356 /* Beckmann microfacet distribution. 357 * D(wh) = exp(-tan^2(a)/m^2) / (PI*m^2*cos^4(a)) 358 * with `a' = arccos(wh.N) and `m' the rougness in ]0, 1] of the surface */ 359 SSF_API const struct ssf_microfacet_distribution_type ssf_beckmann_distribution; 360 361 /* Blinn microfacet distribution. 362 * D(wh) = (e + 2) / (2*PI) * (wh.N)^e 363 * with `e' an exponent in [0, SSF_BLINN_DISTRIBUTION_MAX_EXPONENT] */ 364 SSF_API const struct ssf_microfacet_distribution_type ssf_blinn_distribution; 365 366 /* Pillbox microfacet distribution. 367 * | 0; if |wh.N| >= m 368 * D(wh) = | 1 / (PI * (1 - cos^2(m))); if |wh.N| < m 369 * with `m' the roughness parameter in ]0, 1] */ 370 SSF_API const struct ssf_microfacet_distribution_type ssf_pillbox_distribution; 371 372 /******************************************************************************* 373 * Built-in phase functions. 374 ******************************************************************************/ 375 /* Henyey & Greenstein phase function normalized to 1; p(wo, wi) == pdf(wo, wi). 376 * p(wo, wi) = 1/(4*PI)* (1-g^2) / (1+g^2-2*g*(-wo.wi))^3/2 */ 377 SSF_API const struct ssf_phase_type ssf_phase_hg; 378 379 /* Rayleigh phase function normalized to 1; p(wo, wi) == pdf(wo, wi). 380 * p(wo, wi) = 3/(16*PI) * (1+(-wo.wi)^2) */ 381 SSF_API const struct ssf_phase_type ssf_phase_rayleigh; 382 383 /* RDGFA phase function normalized to 1: 384 * p(wo, wi) = 3/(16*PI) * f(theta)/g * (1+cos(theta)^2); 385 * theta = acos(wo.wi) 386 * 387 * "Effects of multiple scattering on radiative properties of soot fractal 388 * aggregates" J. Yon et al., Journal of Quantitative Spectroscopy and 389 * Radiative Transfer Vol 133, pp. 374-381, 2014 */ 390 SSF_API const struct ssf_phase_type ssf_phase_rdgfa; 391 392 /* Discrete phase function normalized to 1 */ 393 SSF_API const struct ssf_phase_type ssf_phase_discrete; 394 395 /******************************************************************************* 396 * SSF API 397 ******************************************************************************/ 398 SSF_API res_T 399 ssf_get_info 400 (struct ssf_info* info); 401 402 /******************************************************************************* 403 * BSDF API - Bidirectional Scattering Distribution Function. Describes the way 404 * the light is scattered by a surface. Note that by convention the outgoing 405 * direction `wo' and the incoming direction `wi' point outward the surface. 406 * Furthermore, `wo' and the normal `N' must point on the same side of the 407 * surface. As a consequence the reflected or refracted direction `wi' must 408 * point on the same side or on the opposite side of `N', respectively. 409 ******************************************************************************/ 410 SSF_API res_T 411 ssf_bsdf_create 412 (struct mem_allocator* allocator, /* May be NULL <=> Use default allocator */ 413 const struct ssf_bsdf_type* type, 414 struct ssf_bsdf** bsdf); 415 416 SSF_API res_T 417 ssf_bsdf_ref_get 418 (struct ssf_bsdf* bsdf); 419 420 SSF_API res_T 421 ssf_bsdf_ref_put 422 (struct ssf_bsdf* bsdf); 423 424 /* Sample a direction `wi' wrt `wo' whose pdf is BSDF(wo, wi) |wi.n|. Return 425 * the directional reflectance, i.e. pdf to be reflected in *any* direction 426 * wrt to the incident direction `wi' */ 427 SSF_API double 428 ssf_bsdf_sample 429 (struct ssf_bsdf* bsdf, 430 struct ssp_rng* rng, /* Random number generator */ 431 const double wo[3], /* Normalized outgoing direction */ 432 const double N[3], /* Normalized surface normal */ 433 double wi[3], /* Sampled normalized incoming direction */ 434 int* type, /* Type of the sampled component. Combination of ssf_bxdf_flag */ 435 double* pdf); /* PDF to sample wi wrt wo */ 436 437 SSF_API double 438 ssf_bsdf_eval 439 (struct ssf_bsdf* bsdf, 440 const double wo[3], /* Normalized outgoing direction */ 441 const double N[3], /* Normalized surface normal */ 442 const double wi[3]); /* Normalized incoming direction */ 443 444 SSF_API double /* Probability density function*/ 445 ssf_bsdf_pdf 446 (struct ssf_bsdf* bsdf, 447 const double wo[3], /* Normalized outgoing direction */ 448 const double N[3], /* Normalized surface normal */ 449 const double wi[3]); /* Normalized incoming direction */ 450 451 SSF_API res_T 452 ssf_bsdf_get_data 453 (struct ssf_bsdf* bsdf, 454 void** data); 455 456 SSF_API res_T 457 ssf_specular_reflection_setup 458 (struct ssf_bsdf* bsdf, 459 struct ssf_fresnel* fresnel); 460 461 SSF_API res_T 462 ssf_lambertian_reflection_setup 463 (struct ssf_bsdf* bsdf, 464 const double reflectivity); 465 466 SSF_API res_T 467 ssf_microfacet_reflection_setup 468 (struct ssf_bsdf* bsdf, 469 struct ssf_fresnel* fresnel, 470 struct ssf_microfacet_distribution* distrib); 471 472 SSF_API res_T 473 ssf_thin_specular_dielectric_setup 474 (struct ssf_bsdf* bsdf, 475 const double absorption, /* In [0, 1] */ 476 const double eta_i, /* Refraction id of the medium the ray travels in */ 477 const double eta_t, /* Refraction id of the thin dielectric slab */ 478 const double thickness); /* Thickness of the slab */ 479 480 SSF_API res_T 481 ssf_specular_dielectric_dielectric_interface_setup 482 (struct ssf_bsdf* bsdf, 483 const double eta_i, 484 const double eta_t); 485 486 /******************************************************************************* 487 * Phase function API - Describes the way the light is scattered in a medium. 488 * Note that by convention the outgoing direction `wo' and the incoming 489 * direction `wi' point outward the scattering position. 490 ******************************************************************************/ 491 SSF_API res_T 492 ssf_phase_create 493 (struct mem_allocator* allocator, /* May be NULL <=> Use default allocator */ 494 const struct ssf_phase_type* type, 495 struct ssf_phase** phase); 496 497 SSF_API res_T 498 ssf_phase_ref_get 499 (struct ssf_phase* phase); 500 501 SSF_API res_T 502 ssf_phase_ref_put 503 (struct ssf_phase* phase); 504 505 SSF_API void 506 ssf_phase_sample 507 (struct ssf_phase* phase, 508 struct ssp_rng* rng, /* Random number generator */ 509 const double wo[3], /* Normalized outgoing direction */ 510 double wi[3], /* Sampled normalized incoming direction */ 511 double* pdf); /* PDF to sample wi wrt wo */ 512 513 SSF_API double 514 ssf_phase_eval 515 (struct ssf_phase* phase, 516 const double wo[3], /* Normalized outgoing direction */ 517 const double wi[3]); /* Normalized incoming direction */ 518 519 SSF_API double 520 ssf_phase_pdf 521 (struct ssf_phase* phase, 522 const double wo[3], /* Normalized outgoing direction */ 523 const double wi[3]); /* Normalized incoming direction */ 524 525 SSF_API res_T 526 ssf_phase_get_data 527 (struct ssf_phase* bsdf, 528 void** data); 529 530 SSF_API res_T 531 ssf_phase_hg_setup 532 (struct ssf_phase* phase, 533 const double g); /* Asymmetric parameter in [-1, 1] */ 534 535 SSF_API res_T 536 ssf_phase_discrete_setup 537 (struct ssf_phase* phase, 538 const struct ssf_discrete_setup_args* args); 539 540 /******************************************************************************* 541 * RDGFA phase function 542 ******************************************************************************/ 543 SSF_API res_T 544 ssf_phase_rdgfa_setup 545 (struct ssf_phase* phase, 546 const struct ssf_phase_rdgfa_setup_args* args); 547 548 SSF_API res_T 549 ssf_phase_rdgfa_get_desc 550 (const struct ssf_phase* phase, 551 struct ssf_phase_rdgfa_desc* desc); 552 553 SSF_API res_T 554 ssf_phase_rdgfa_get_interval 555 (const struct ssf_phase* phase, 556 const size_t interval_id, /* In [0, desc.nintervals[ */ 557 struct ssf_phase_rdgfa_interval* interval); 558 559 /******************************************************************************* 560 * Fresnel API - Define the equation of the fresnel term 561 ******************************************************************************/ 562 SSF_API res_T 563 ssf_fresnel_create 564 (struct mem_allocator* allocator, 565 const struct ssf_fresnel_type* type, 566 struct ssf_fresnel** fresnel); 567 568 SSF_API res_T 569 ssf_fresnel_ref_get 570 (struct ssf_fresnel* fresnel); 571 572 SSF_API res_T 573 ssf_fresnel_ref_put 574 (struct ssf_fresnel* fresnel); 575 576 SSF_API double 577 ssf_fresnel_eval 578 (struct ssf_fresnel* fresnel, 579 const double cos_theta); /* Cos between facet normal and incoming dir */ 580 581 /* Retrieve the internal data of the Fresnel term. Usefull for user defined 582 * Fresnel terms on which the caller has to retrieve their data to setup the 583 * parameters of their Fresnel equation. */ 584 SSF_API res_T 585 ssf_fresnel_get_data 586 (struct ssf_fresnel* fresnel, 587 void** data); 588 589 SSF_API res_T 590 ssf_fresnel_dielectric_dielectric_setup 591 (struct ssf_fresnel* fresnel, 592 /* Refraction id of the medium the incoming ray travels in */ 593 const double eta_i, 594 /* Refraction id of the medium the outgoing transmission ray travels in */ 595 const double eta_t); 596 597 SSF_API res_T 598 ssf_fresnel_dielectric_conductor_setup 599 (struct ssf_fresnel* fresnel, 600 const double eta_i, /* Refraction id of the dielectric medium */ 601 const double eta_t, /* Real part of the refraction id of the conductor */ 602 const double k_t); /* Imaginary part of the refraction id of the conductor */ 603 604 SSF_API res_T 605 ssf_fresnel_constant_setup 606 (struct ssf_fresnel* fresnel, 607 const double constant); /* in [0, 1] */ 608 609 /******************************************************************************* 610 * Microfacet Distribution API - Note that by convention the outgoing direction 611 * `wo' and the half vector `wh' point outward the surface. 612 ******************************************************************************/ 613 SSF_API res_T 614 ssf_microfacet_distribution_create 615 (struct mem_allocator* allocator, 616 const struct ssf_microfacet_distribution_type* type, 617 struct ssf_microfacet_distribution** distrib); 618 619 SSF_API res_T 620 ssf_microfacet_distribution_ref_get 621 (struct ssf_microfacet_distribution* distrib); 622 623 SSF_API res_T 624 ssf_microfacet_distribution_ref_put 625 (struct ssf_microfacet_distribution* distrib); 626 627 SSF_API double 628 ssf_microfacet_distribution_eval 629 (struct ssf_microfacet_distribution* distrib, 630 const double N[3], /* Normalized Z-direction of the distribution */ 631 const double wh[3]); /* Normalized half vector */ 632 633 SSF_API void 634 ssf_microfacet_distribution_sample 635 (struct ssf_microfacet_distribution* distrib, 636 struct ssp_rng* rng, /* Random number generator */ 637 const double N[3], /* Normalized Z-direction of the distribution */ 638 double wh[3], /* Normalized half vector */ 639 double* pdf); /* PDF of the sampled half vector */ 640 641 SSF_API double 642 ssf_microfacet_distribution_pdf 643 (struct ssf_microfacet_distribution* distrib, 644 const double N[3], /* Normalized Z-direction of the distribution */ 645 const double wh[3]); /* Normalized half vector */ 646 647 /* Retrieve the internal data of the microfacet distribution. Usefull for user 648 * defined distributions on which the caller has to retrieve their data to 649 * setup their parameters. */ 650 SSF_API res_T 651 ssf_microfacet_distribution_get_data 652 (struct ssf_microfacet_distribution* distrib, 653 void** data); 654 655 SSF_API res_T 656 ssf_beckmann_distribution_setup 657 (struct ssf_microfacet_distribution* distrib, 658 const double roughness); /* In ]0, 1] */ 659 660 SSF_API res_T 661 ssf_blinn_distribution_setup 662 (struct ssf_microfacet_distribution* distrib, 663 const double exponent); /* in [0, SSF_BLINN_DISTRIBUTION_MAX_EXPONENT] */ 664 665 SSF_API res_T 666 ssf_pillbox_distribution_setup 667 (struct ssf_microfacet_distribution* distrib, 668 const double roughness); /* In ]0, 1] */ 669 670 END_DECLS 671 672 #endif /* SSF_H */