star-sf

Set of surface and volume scattering functions
git clone git://git.meso-star.fr/star-sf.git
Log | Files | Refs | README | LICENSE

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