// BSDF Method Definitions Spectrum BSDF::Sample_f(const Vector &wo, Vector *wi, BxDFType flags, BxDFType *sampledType) const { float pdf; Spectrum f = Sample_f(wo, wi, RandomFloat(), RandomFloat(), RandomFloat(), &pdf, flags, sampledType); if (!f.Black() && pdf > 0.) f /= pdf; return f; }
Spectrum BxDF::rho(const Vector3f &w, int nSamples, const Point2f *u) const { Spectrum r(0.); for (int i = 0; i < nSamples; ++i) { // Estimate one term of $\rho_\roman{hd}$ Vector3f wi; Float pdf = 0; Spectrum f = Sample_f(w, &wi, u[i], &pdf); if (pdf > 0) r += f * AbsCosTheta(wi) / pdf; } return r / nSamples; }
Spectrum BxDF::rho(int nSamples, const Point2f *u1, const Point2f *u2) const { Spectrum r(0.f); for (int i = 0; i < nSamples; ++i) { // Estimate one term of $\rho_\roman{hh}$ Vector3f wo, wi; wo = UniformSampleHemisphere(u1[i]); Float pdfo = UniformHemispherePdf(), pdfi = 0; Spectrum f = Sample_f(wo, &wi, u2[i], &pdfi); if (pdfi > 0) r += f * AbsCosTheta(wi) * AbsCosTheta(wo) / (pdfo * pdfi); } return r / (Pi * nSamples); }
Spectrum BxDF::rho(const Vector &w, int nSamples, float *samples) const { if (!samples) { samples = (float *)alloca(2 * nSamples * sizeof(float)); LatinHypercube(samples, nSamples, 2); } Spectrum r = 0.; for (int i = 0; i < nSamples; ++i) { // Estimate one term of $\rho_{dh}$ Vector wi; float pdf = 0.f; Spectrum f = Sample_f(w, &wi, samples[2*i], samples[2*i+1], &pdf); if (pdf > 0.) r += f * fabsf(wi.z) / pdf; } return r / nSamples; }
Spectrum BxDF::rho(int nSamples, float *samples) const { if (!samples) { samples = (float *)alloca(4 * nSamples * sizeof(float)); LatinHypercube(samples, nSamples, 4); } Spectrum r = 0.; for (int i = 0; i < nSamples; ++i) { // Estimate one term of $\rho_{hh}$ Vector wo, wi; wo = UniformSampleHemisphere(samples[4*i], samples[4*i+1]); float pdf_o = INV_TWOPI, pdf_i = 0.f; Spectrum f = Sample_f(wo, &wi, samples[4*i+2], samples[4*i+3], &pdf_i); if (pdf_i > 0.) r += f * fabsf(wi.z * wo.z) / (pdf_o * pdf_i); } return r / (M_PI*nSamples); }