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_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