ssf_specular_reflection.c (3140B)
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 #include "ssf_optics.h" 19 20 #include <rsys/double3.h> 21 22 struct specular_reflection { 23 struct ssf_fresnel* fresnel; 24 }; 25 26 /******************************************************************************* 27 * Private functions 28 ******************************************************************************/ 29 static void 30 specular_reflection_release(void* data) 31 { 32 struct specular_reflection* brdf = data; 33 ASSERT(data); 34 if(brdf->fresnel) SSF(fresnel_ref_put(brdf->fresnel)); 35 } 36 37 static double 38 specular_reflection_sample 39 (void* data, 40 struct ssp_rng* rng, 41 const double wo[3], 42 const double N[3], 43 double wi[3], 44 int* type, 45 double* pdf) 46 { 47 struct specular_reflection* brdf = data; 48 double cos_wo_N; 49 double cos_wi_N; 50 ASSERT(rng && wi && N && wo); 51 ASSERT(d3_is_normalized(wo) && d3_is_normalized(N) && d3_dot(wo, N) > 0); 52 (void)rng; 53 54 /* Reflect the outgoing direction wo with respect to the surface normal N */ 55 reflect(wi, wo, N); 56 if(pdf) *pdf = INF; 57 if(type) *type = SSF_REFLECTION | SSF_SPECULAR; 58 59 cos_wi_N = cos_wo_N = d3_dot(wo, N); 60 return ssf_fresnel_eval(brdf->fresnel, cos_wi_N); 61 } 62 63 static double 64 specular_reflection_eval 65 (void* data, const double wo[3], const double N[3], const double wi[3]) 66 { 67 (void)data, (void)wi, (void)N, (void)wo; 68 return 0.0; 69 } 70 71 static double 72 specular_reflection_pdf 73 (void* data, const double wo[3], const double N[3], const double wi[3]) 74 { 75 (void)data, (void)wi, (void)N, (void)wo; 76 return 0.0; 77 } 78 79 /******************************************************************************* 80 * Exported symbols 81 ******************************************************************************/ 82 const struct ssf_bsdf_type ssf_specular_reflection = { 83 NULL, 84 specular_reflection_release, 85 specular_reflection_sample, 86 specular_reflection_eval, 87 specular_reflection_pdf, 88 sizeof(struct specular_reflection), 89 ALIGNOF(struct specular_reflection) 90 }; 91 92 res_T 93 ssf_specular_reflection_setup 94 (struct ssf_bsdf* bsdf, 95 struct ssf_fresnel* fresnel) 96 { 97 struct specular_reflection* spec; 98 if(!bsdf || !fresnel) 99 return RES_BAD_ARG; 100 if(!BSDF_TYPE_EQ(&bsdf->type, &ssf_specular_reflection)) 101 return RES_BAD_ARG; 102 103 spec = bsdf->data; 104 105 if(spec->fresnel != fresnel) { 106 if(spec->fresnel) SSF(fresnel_ref_put(spec->fresnel)); 107 SSF(fresnel_ref_get(fresnel)); 108 spec->fresnel = fresnel; 109 } 110 return RES_OK; 111 } 112