ssf_lambertian_reflection.c (3044B)
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 "ssf_bsdf_c.h" 18 19 #include <rsys/double3.h> 20 #include <rsys/double33.h> 21 22 #include <star/ssp.h> 23 24 struct lambertian_reflection { 25 double reflectivity; 26 }; 27 28 /******************************************************************************* 29 * Private functions 30 ******************************************************************************/ 31 static double 32 lambertian_reflection_eval 33 (void* data, const double wo[3], const double N[3], const double wi[3]) 34 { 35 struct lambertian_reflection* brdf = data; 36 ASSERT(data && N && wi); 37 ASSERT(d3_is_normalized(N) && d3_is_normalized(wi)); 38 ASSERT(d3_dot(wi, N) > 0 && d3_dot(wo, N) > 0); 39 (void)wo, (void)N, (void)wi; 40 return brdf->reflectivity / PI; 41 } 42 43 static double 44 lambertian_reflection_sample 45 (void* data, 46 struct ssp_rng* rng, 47 const double wo[3], 48 const double N[3], 49 double wi[3], 50 int* type, 51 double* pdf) 52 { 53 double sample[3]; 54 ASSERT(data && rng && wo && N && wi); 55 ASSERT(d3_is_normalized(wo) && d3_is_normalized(N) && d3_dot(wo, N) > 0); 56 (void)wo; 57 58 ssp_ran_hemisphere_cos(rng, N, sample, pdf); 59 d3_set(wi, sample); 60 if(type) *type = SSF_REFLECTION | SSF_DIFFUSE; 61 return ((struct lambertian_reflection*)data)->reflectivity; 62 } 63 64 static double 65 lambertian_reflection_pdf 66 (void* data, const double wo[3], const double N[3], const double wi[3]) 67 { 68 double cos_wi_N; 69 ASSERT(data && wi && N); 70 ASSERT(d3_is_normalized(N) && d3_is_normalized(wi)); 71 (void)data, (void)wo; 72 cos_wi_N = d3_dot(wi, N); 73 return cos_wi_N <= 0.0 ? 0.0 : cos_wi_N / PI; 74 } 75 76 /******************************************************************************* 77 * Exorted symbols 78 ******************************************************************************/ 79 const struct ssf_bsdf_type ssf_lambertian_reflection = { 80 NULL, 81 NULL, 82 lambertian_reflection_sample, 83 lambertian_reflection_eval, 84 lambertian_reflection_pdf, 85 sizeof(struct lambertian_reflection), 86 ALIGNOF(struct lambertian_reflection) 87 }; 88 89 res_T 90 ssf_lambertian_reflection_setup(struct ssf_bsdf* bsdf, const double reflectivity) 91 { 92 if(!bsdf || reflectivity < 0 || reflectivity > 1) return RES_BAD_ARG; 93 if(!BSDF_TYPE_EQ(&bsdf->type, &ssf_lambertian_reflection)) return RES_BAD_ARG; 94 ((struct lambertian_reflection*)bsdf->data)->reflectivity = reflectivity; 95 return RES_OK; 96 } 97