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 "lafortune.h"
00025 #include "spectrum.h"
00026 #include "mc.h"
00027
00028 using namespace lux;
00029
00030 Lafortune::Lafortune(const SWCSpectrum &xx, const SWCSpectrum &yy, const SWCSpectrum &zz,
00031 const SWCSpectrum &e, BxDFType t)
00032 : BxDF(t), x(xx), y(yy), z(zz), exponent(e)
00033 {
00034 }
00035 void Lafortune::f(const TsPack *tspack, const Vector &wo, const Vector &wi, SWCSpectrum *const f_) const {
00036 SWCSpectrum v(x * (wo.x * wi.x) + y * (wo.y * wi.y) + z * (wo.z * wi.z));
00037 *f_ += v.Pow(exponent);
00038 }
00039
00040 bool Lafortune::Sample_f(const TsPack *tspack, const Vector &wo, Vector *wi,
00041 float u1, float u2, SWCSpectrum *const f_, float *pdf, float *pdfBack, bool reverse) const {
00042 const float xlum = x.Y(tspack);
00043 const float ylum = y.Y(tspack);
00044 const float zlum = z.Y(tspack);
00045 const float costheta = powf(u1, 1.f / (.8f * exponent.Filter(tspack) + 1.f));
00046 const float sintheta = sqrtf(max(0.f, 1.f - costheta * costheta));
00047 const float phi = u2 * 2.f * M_PI;
00048 const Vector lobeCenter(Normalize(Vector(xlum * wo.x, ylum * wo.y, zlum * wo.z)));
00049 Vector lobeX, lobeY;
00050 CoordinateSystem(lobeCenter, &lobeX, &lobeY);
00051 *wi = SphericalDirection(sintheta, costheta, phi, lobeX, lobeY,
00052 lobeCenter);
00053 if (!SameHemisphere(wo, *wi))
00054 return false;
00055 *pdf = Pdf(tspack, wo, *wi);
00056 if (pdfBack)
00057 *pdfBack = Pdf(tspack, *wi, wo);
00058 *f_ = SWCSpectrum(0.f);
00059 if (reverse)
00060 f(tspack, *wi, wo, f_);
00061 else
00062 f(tspack, wo, *wi, f_);
00063 return true;
00064 }
00065
00066
00067 float Lafortune::Pdf(const TsPack *tspack, const Vector &wo, const Vector &wi) const {
00068 if (!SameHemisphere(wo, wi)) return 0.f;
00069 const float xlum = x.Y(tspack);
00070 const float ylum = y.Y(tspack);
00071 const float zlum = z.Y(tspack);
00072 const Vector lobeCenter(Normalize(Vector(wo.x * xlum, wo.y * ylum, wo.z * zlum)));
00073 const float e = .8f * exponent.Y(tspack);
00074 return (e + 1.f) * powf(max(0.f, Dot(wi, lobeCenter)), e);
00075 }
00076