00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "microfacet.h"
00025 #include "spectrum.h"
00026 #include "mc.h"
00027 #include "fresnel.h"
00028 #include "microfacetdistribution.h"
00029
00030 using namespace lux;
00031
00032 Microfacet::Microfacet(const SWCSpectrum &reflectance,
00033 Fresnel *fr,
00034 MicrofacetDistribution *d)
00035 : BxDF(BxDFType(BSDF_REFLECTION | BSDF_GLOSSY)),
00036 R(reflectance), distribution(d), fresnel(fr)
00037 {
00038 }
00039
00040 void Microfacet::f(const TsPack *tspack, const Vector &wo,
00041 const Vector &wi, SWCSpectrum *const f_) const
00042 {
00043 float cosThetaO = fabsf(CosTheta(wo));
00044 float cosThetaI = fabsf(CosTheta(wi));
00045 Vector wh = Normalize(wi + wo);
00046 float cosThetaH = Dot(wi, wh);
00047 SWCSpectrum F;
00048 fresnel->Evaluate(tspack, cosThetaH, &F);
00049 f_->AddWeighted(distribution->D(wh) * G(wo, wi, wh) /
00050 (4.f * cosThetaI * cosThetaO), R * F);
00051 }
00052
00053 bool Microfacet::Sample_f(const TsPack *tspack, const Vector &wo, Vector *wi,
00054 float u1, float u2, SWCSpectrum *const f_, float *pdf,
00055 float *pdfBack, bool reverse) const
00056 {
00057 distribution->Sample_f(wo, wi, u1, u2, pdf);
00058 if (pdfBack)
00059 *pdfBack = Pdf(tspack, *wi, wo);
00060 if (!SameHemisphere(wo, *wi))
00061 return false;
00062
00063 *f_ = SWCSpectrum(0.f);
00064 if (reverse)
00065 f(tspack, *wi, wo, f_);
00066 else
00067 f(tspack, wo, *wi, f_);
00068 return true;
00069 }
00070 float Microfacet::Pdf(const TsPack *tspack, const Vector &wo,
00071 const Vector &wi) const
00072 {
00073 if (!SameHemisphere(wo, wi))
00074 return 0.f;
00075 return distribution->Pdf(wo, wi);
00076 }
00077