00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LUX_BXDF_H
00024 #define LUX_BXDF_H
00025
00026 #include "lux.h"
00027 #include "geometry/raydifferential.h"
00028 #include "spectrum.h"
00029 #include "memory.h"
00030
00031 namespace lux
00032 {
00033
00034
00035 inline float CosTheta(const Vector &w) { return w.z; }
00036 inline float SinTheta(const Vector &w) {
00037 return sqrtf(max(0.f, 1.f - w.z*w.z));
00038 }
00039 inline float SinTheta2(const Vector &w) {
00040 return 1.f - CosTheta(w)*CosTheta(w);
00041 }
00042 inline float CosPhi(const Vector &w) {
00043 return w.x / SinTheta(w);
00044 }
00045 inline float SinPhi(const Vector &w) {
00046 return w.y / SinTheta(w);
00047 }
00048 inline bool SameHemisphere(const Vector &w,
00049 const Vector &wp) {
00050 return w.z * wp.z > 0.f;
00051 }
00052
00053 enum BxDFType {
00054 BSDF_REFLECTION = 1<<0,
00055 BSDF_TRANSMISSION = 1<<1,
00056 BSDF_DIFFUSE = 1<<2,
00057 BSDF_GLOSSY = 1<<3,
00058 BSDF_SPECULAR = 1<<4,
00059 BSDF_ALL_TYPES = BSDF_DIFFUSE |
00060 BSDF_GLOSSY |
00061 BSDF_SPECULAR,
00062 BSDF_ALL_REFLECTION = BSDF_REFLECTION |
00063 BSDF_ALL_TYPES,
00064 BSDF_ALL_TRANSMISSION = BSDF_TRANSMISSION |
00065 BSDF_ALL_TYPES,
00066 BSDF_ALL = BSDF_ALL_REFLECTION |
00067 BSDF_ALL_TRANSMISSION
00068 };
00069 class BSDF {
00070 public:
00071
00072 BSDF(const DifferentialGeometry &dgs, const Normal &ngeom,
00073 float eta = 1.f);
00074 virtual int NumComponents() const = 0;
00075 virtual int NumComponents(BxDFType flags) const = 0;
00076 virtual inline void SetCompositingParams(CompositingParams *cp) {
00077 compParams = cp;
00078 }
00079 bool HasShadingGeometry() const {
00080 return (nn.x != ng.x || nn.y != ng.y || nn.z != ng.z);
00081 }
00082 Vector WorldToLocal(const Vector &v) const {
00083 return Vector(Dot(v, sn), Dot(v, tn), Dot(v, nn));
00084 }
00085 Vector LocalToWorld(const Vector &v) const {
00086 return Vector(sn.x * v.x + tn.x * v.y + nn.x * v.z,
00087 sn.y * v.x + tn.y * v.y + nn.y * v.z,
00088 sn.z * v.x + tn.z * v.y + nn.z * v.z);
00089 }
00094 virtual bool Sample_f(const TsPack *tspack, const Vector &o, Vector *wi,
00095 float u1, float u2, float u3, SWCSpectrum *const f, float *pdf,
00096 BxDFType flags = BSDF_ALL, BxDFType *sampledType = NULL,
00097 float *pdfBack = NULL, bool reverse = false) const = 0;
00098 virtual float Pdf(const TsPack *tspack, const Vector &wo,
00099 const Vector &wi, BxDFType flags = BSDF_ALL) const = 0;
00100 virtual SWCSpectrum f(const TsPack *tspack, const Vector &woW,
00101 const Vector &wiW, BxDFType flags = BSDF_ALL) const = 0;
00102 virtual SWCSpectrum rho(const TsPack *tspack,
00103 BxDFType flags = BSDF_ALL) const = 0;
00104 virtual SWCSpectrum rho(const TsPack *tspack, const Vector &wo,
00105 BxDFType flags = BSDF_ALL) const = 0;
00106
00107 static void *Alloc(const TsPack *tspack, u_int sz) {
00108 return tspack->arena->Alloc(sz);
00109 }
00110 static void FreeAll(const TsPack *tspack) { tspack->arena->FreeAll(); }
00111
00112
00113 const DifferentialGeometry dgShading;
00114 const float eta;
00115 Normal nn, ng;
00116
00117
00118 CompositingParams *compParams;
00119
00120 protected:
00121
00122 virtual ~BSDF() { }
00123
00124 Vector sn, tn;
00125 };
00126 #define BSDF_ALLOC(TSPACK,T) new (BSDF::Alloc((TSPACK), sizeof(T))) T
00127
00128
00129 class SingleBSDF : public BSDF {
00130 public:
00131
00132 SingleBSDF(const DifferentialGeometry &dgs, const Normal &ngeom,
00133 BxDF *b, float e = 1.f) : BSDF(dgs, ngeom, e), bxdf(b) { }
00134 virtual inline int NumComponents() const { return 1; }
00135 virtual inline int NumComponents(BxDFType flags) const;
00140 virtual bool Sample_f(const TsPack *tspack, const Vector &o, Vector *wi,
00141 float u1, float u2, float u3, SWCSpectrum *const f, float *pdf,
00142 BxDFType flags = BSDF_ALL, BxDFType *sampledType = NULL,
00143 float *pdfBack = NULL, bool reverse = false) const;
00144 virtual float Pdf(const TsPack *tspack, const Vector &wo,
00145 const Vector &wi, BxDFType flags = BSDF_ALL) const;
00146 virtual SWCSpectrum f(const TsPack *tspack, const Vector &woW,
00147 const Vector &wiW, BxDFType flags = BSDF_ALL) const;
00148 virtual SWCSpectrum rho(const TsPack *tspack,
00149 BxDFType flags = BSDF_ALL) const;
00150 virtual SWCSpectrum rho(const TsPack *tspack, const Vector &wo,
00151 BxDFType flags = BSDF_ALL) const;
00152
00153 protected:
00154
00155 virtual ~SingleBSDF() { }
00156
00157 BxDF *bxdf;
00158 };
00159
00160
00161 class MultiBSDF : public BSDF {
00162 public:
00163
00164 MultiBSDF(const DifferentialGeometry &dgs, const Normal &ngeom,
00165 float eta = 1.f);
00166 inline void Add(BxDF *bxdf);
00167 virtual inline int NumComponents() const { return nBxDFs; }
00168 virtual inline int NumComponents(BxDFType flags) const;
00173 virtual bool Sample_f(const TsPack *tspack, const Vector &o, Vector *wi,
00174 float u1, float u2, float u3, SWCSpectrum *const f, float *pdf,
00175 BxDFType flags = BSDF_ALL, BxDFType *sampledType = NULL,
00176 float *pdfBack = NULL, bool reverse = false) const;
00177 virtual float Pdf(const TsPack *tspack, const Vector &wo,
00178 const Vector &wi, BxDFType flags = BSDF_ALL) const;
00179 virtual SWCSpectrum f(const TsPack *tspack, const Vector &woW,
00180 const Vector &wiW, BxDFType flags = BSDF_ALL) const;
00181 virtual SWCSpectrum rho(const TsPack *tspack,
00182 BxDFType flags = BSDF_ALL) const;
00183 virtual SWCSpectrum rho(const TsPack *tspack, const Vector &wo,
00184 BxDFType flags = BSDF_ALL) const;
00185
00186 protected:
00187
00188 virtual ~MultiBSDF() { }
00189
00190 int nBxDFs;
00191 #define MAX_BxDFS 8
00192 BxDF *bxdfs[MAX_BxDFS];
00193 };
00194
00195
00196 class MixBSDF : public BSDF {
00197 public:
00198
00199 MixBSDF(const DifferentialGeometry &dgs, const Normal &ngeom);
00200 inline void Add(float weight, BSDF *bsdf);
00201 virtual inline int NumComponents() const;
00202 virtual inline int NumComponents(BxDFType flags) const;
00203 virtual inline void SetCompositingParams(CompositingParams *cp) {
00204 compParams = cp;
00205 for (int i = 0; i < nBSDFs; ++i)
00206 bsdfs[i]->SetCompositingParams(cp);
00207 }
00212 virtual bool Sample_f(const TsPack *tspack, const Vector &o, Vector *wi,
00213 float u1, float u2, float u3, SWCSpectrum *const f, float *pdf,
00214 BxDFType flags = BSDF_ALL, BxDFType *sampledType = NULL,
00215 float *pdfBack = NULL, bool reverse = false) const;
00216 virtual float Pdf(const TsPack *tspack, const Vector &wo,
00217 const Vector &wi, BxDFType flags = BSDF_ALL) const;
00218 virtual SWCSpectrum f(const TsPack *tspack, const Vector &woW,
00219 const Vector &wiW, BxDFType flags = BSDF_ALL) const;
00220 virtual SWCSpectrum rho(const TsPack *tspack,
00221 BxDFType flags = BSDF_ALL) const;
00222 virtual SWCSpectrum rho(const TsPack *tspack, const Vector &wo,
00223 BxDFType flags = BSDF_ALL) const;
00224 private:
00225
00226 virtual ~MixBSDF() { }
00227
00228 int nBSDFs;
00229 BSDF *bsdfs[MAX_BxDFS];
00230 float weights[MAX_BxDFS];
00231 float totalWeight;
00232 };
00233
00234
00235 class BxDF {
00236 public:
00237
00238 virtual ~BxDF() { }
00239 BxDF(BxDFType t) : type(t) { }
00240 bool MatchesFlags(BxDFType flags) const {
00241 return (type & flags) == type;
00242 }
00247 virtual void f(const TsPack *tspack, const Vector &wo,
00248 const Vector &wi, SWCSpectrum *const f) const = 0;
00253 virtual bool Sample_f(const TsPack *tspack, const Vector &wo, Vector *wi,
00254 float u1, float u2, SWCSpectrum *const f, float *pdf, float *pdfBack = NULL,
00255 bool reverse = false) const;
00256 virtual SWCSpectrum rho(const TsPack *tspack, const Vector &wo,
00257 int nSamples = 16,
00258 float *samples = NULL) const;
00259 virtual SWCSpectrum rho(const TsPack *tspack, int nSamples = 16,
00260 float *samples = NULL) const;
00261 virtual float Weight(const TsPack *tspack, const Vector &wo) const;
00262 virtual float Pdf(const TsPack *tspack, const Vector &wi, const Vector &wo) const;
00263
00264 const BxDFType type;
00265 };
00266 class BRDFToBTDF : public BxDF {
00267 public:
00268
00269 BRDFToBTDF(BxDF *b, float ei = 1.f, float et = 1.f, float c = 0.f)
00270 : BxDF(BxDFType(b->type ^
00271 (BSDF_REFLECTION | BSDF_TRANSMISSION))),
00272 etai(ei), etat(et), cb(c), brdf(b) {}
00273 virtual ~BRDFToBTDF() { }
00274 static Vector otherHemisphere(const Vector &w) {
00275 return Vector(w.x, w.y, -w.z);
00276 }
00277 virtual SWCSpectrum rho(const TsPack *tspack, const Vector &w, int nSamples,
00278 float *samples) const {
00279 return brdf->rho(tspack, otherHemisphere(w), nSamples, samples);
00280 }
00281 virtual SWCSpectrum rho(const TsPack *tspack, int nSamples, float *samples) const {
00282 return brdf->rho(tspack, nSamples, samples);
00283 }
00284 virtual void f(const TsPack *tspack, const Vector &wo, const Vector &wi, SWCSpectrum *const f) const;
00285 virtual bool Sample_f(const TsPack *tspack, const Vector &wo, Vector *wi,
00286 float u1, float u2, SWCSpectrum *const f, float *pdf, float *pdfBack = NULL,
00287 bool reverse = false) const;
00288 virtual float Weight(const TsPack *tspack, const Vector &wo) const {
00289 return brdf->Weight(tspack, wo);
00290 }
00291 virtual float Pdf(const TsPack *tspack, const Vector &wo, const Vector &wi) const;
00292 private:
00293 float etai, etat, cb;
00294 BxDF *brdf;
00295 };
00296
00297
00298 inline int SingleBSDF::NumComponents(BxDFType flags) const
00299 {
00300 return bxdf->MatchesFlags(flags) ? 1 : 0;
00301 }
00302 inline void MultiBSDF::Add(BxDF *b)
00303 {
00304 BOOST_ASSERT(nBxDFs < MAX_BxDFS);
00305 bxdfs[nBxDFs++] = b;
00306 }
00307 inline int MultiBSDF::NumComponents(BxDFType flags) const
00308 {
00309 int num = 0;
00310 for (int i = 0; i < nBxDFs; ++i)
00311 if (bxdfs[i]->MatchesFlags(flags)) ++num;
00312 return num;
00313 }
00314 inline void MixBSDF::Add(float weight, BSDF *bsdf)
00315 {
00316 BOOST_ASSERT(nBSDFs < MAX_BxDFS);
00317 weights[nBSDFs] = weight;
00318 bsdfs[nBSDFs++] = bsdf;
00319 totalWeight += weight;
00320 }
00321 inline int MixBSDF::NumComponents() const
00322 {
00323 int num = 0;
00324 for (int i = 0; i < nBSDFs; ++i)
00325 num += bsdfs[i]->NumComponents();
00326 return num;
00327 }
00328 inline int MixBSDF::NumComponents(BxDFType flags) const
00329 {
00330 int num = 0;
00331 for (int i = 0; i < nBSDFs; ++i)
00332 num += bsdfs[i]->NumComponents(flags);
00333 return num;
00334 }
00335
00336 }
00337
00338 #endif // LUX_BXDF_H