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 "color.h"
00026 #include "spectrum.h"
00027 #include "mc.h"
00028 #include "sampling.h"
00029 #include "fresnel.h"
00030 #include "microfacetdistribution.h"
00031 #include <stdarg.h>
00032
00033 using namespace lux;
00034
00035 Microfacet::Microfacet(const SWCSpectrum &reflectance,
00036 Fresnel *f,
00037 MicrofacetDistribution *d)
00038 : BxDF(BxDFType(BSDF_REFLECTION | BSDF_GLOSSY)),
00039 R(reflectance), distribution(d), fresnel(f) {
00040 }
00041
00042 SWCSpectrum Microfacet::f(const Vector &wo,
00043 const Vector &wi) const {
00044 float cosThetaO = fabsf(CosTheta(wo));
00045 float cosThetaI = fabsf(CosTheta(wi));
00046 Vector wh = Normalize(wi + wo);
00047 float cosThetaH = Dot(wi, wh);
00048 SWCSpectrum F = fresnel->Evaluate(cosThetaH);
00049 return R * distribution->D(wh) * G(wo, wi, wh) * F /
00050 (4.f * cosThetaI * cosThetaO);
00051 }
00052
00053 SWCSpectrum Microfacet::Sample_f(const Vector &wo, Vector *wi,
00054 float u1, float u2, float *pdf, float *pdfBack) const {
00055 distribution->Sample_f(wo, wi, u1, u2, pdf);
00056 if (pdfBack)
00057 *pdfBack = Pdf(*wi, wo);
00058 if (!SameHemisphere(wo, *wi)) return SWCSpectrum(0.f);
00059 return f(wo, *wi);
00060 }
00061 float Microfacet::Pdf(const Vector &wo,
00062 const Vector &wi) const {
00063 if (!SameHemisphere(wo, wi)) return 0.f;
00064 return distribution->Pdf(wo, wi);
00065 }
00066