// BxDF Method Definitions bool BxDF::SampleF(const SpectrumWavelengths &sw, const Vector &wo, Vector *wi, float u1, float u2, SWCSpectrum *const f, float *pdf, float *pdfBack, bool reverse) const { // Cosine-sample the hemisphere, flipping the direction if necessary *wi = CosineSampleHemisphere(u1, u2); if (wo.z < 0.f) wi->z = -(wi->z); // wi may be in the tangent plane, which will // fail the SameHemisphere test in Pdf() if (!SameHemisphere(wo, *wi)) return false; *pdf = Pdf(sw, wo, *wi); if (pdfBack) *pdfBack = Pdf(sw, *wi, wo); *f = SWCSpectrum(0.f); if (reverse) F(sw, *wi, wo, f); else F(sw, wo, *wi, f); *f /= *pdf; return true; }
SWCSpectrum FresnelApproxEta(const SWCSpectrum &Fr) { SWCSpectrum sqrtReflectance = Sqrt(Fr.Clamp(0.f, .999f)); return (SWCSpectrum(1.f) + sqrtReflectance) / (SWCSpectrum(1.f) - sqrtReflectance); }
SWCSpectrum FresnelApproxK(const SWCSpectrum &Fr) { SWCSpectrum reflectance = Fr.Clamp(0.f, .999f); return 2.f * Sqrt(reflectance / (SWCSpectrum(1.f) - reflectance)); }
// Utility Functions void FrDiel(float cosi, float cost, const SWCSpectrum &etai, const SWCSpectrum &etat, SWCSpectrum *const f) { FrDiel2(cosi, SWCSpectrum(cost), etat / etai, f); }