bool HomogeneousVolumeDensity::SampleDirection(const Point &p, const Vector& wi, Vector& wo, float* pdf, RNG &rng) const { const Point Pobj = WorldToVolume(p); if(extent.Inside(Pobj)) { wo = SampleHG(wi, g, rng.RandomFloat(), rng.RandomFloat()); *pdf = PhaseHG(wi, wo, g); return true; } else { return false; } }
// HenyeyGreenstein Method Definitions Float HenyeyGreenstein::Sample_p(const Vector3f &wo, Vector3f *wi, const Point2f &u) const { // Compute $\cos \theta$ for Henyey--Greenstein sample Float cosTheta; if (std::abs(g) < 1e-3) cosTheta = 1 - 2 * u[0]; else { Float sqrTerm = (1 - g * g) / (1 - g + 2 * g * u[0]); cosTheta = (1 + g * g - sqrTerm * sqrTerm) / (2 * g); } // Compute direction _wi_ for Henyey--Greenstein sample Float sinTheta = std::sqrt(std::max((Float)0, 1 - cosTheta * cosTheta)); Float phi = 2 * Pi * u[1]; Vector3f v1, v2; CoordinateSystem(wo, &v1, &v2); *wi = SphericalDirection(sinTheta, cosTheta, phi, v1, v2, -wo); return PhaseHG(-cosTheta, g); }
Float BeamDiffusionSS(Float sigma_s, Float sigma_a, Float g, Float eta, Float r) { // Compute material parameters and minimum $t$ below the critical angle Float sigma_t = sigma_a + sigma_s, rho = sigma_s / sigma_t; Float tCrit = r * std::sqrt(eta * eta - 1); Float Ess = 0; const int nSamples = 100; for (int i = 0; i < nSamples; ++i) { // Evaluate single scattering integrand and add to _Ess_ Float ti = tCrit - std::log(1 - (i + .5f) / nSamples) / sigma_t; // Determine length $d$ of connecting segment and $\cos\theta_\roman{o}$ Float d = std::sqrt(r * r + ti * ti); Float cosThetaO = ti / d; // Add contribution of single scattering at depth $t$ Ess += rho * std::exp(-sigma_t * (d + tCrit)) / (d * d) * PhaseHG(cosThetaO, g) * (1 - FrDielectric(-cosThetaO, 1, eta)) * std::abs(cosThetaO); } return Ess / nSamples; }
float HGPdf(const Vector &w, const Vector &wp, float g) { return PhaseHG(w, wp, g); }
Float HenyeyGreenstein::p(const Vector3f &wo, const Vector3f &wi) const { return PhaseHG(Dot(wo, wi), g); }
float p(const Point &p, const Vector &wi, const Vector &wo) const { if (!extent.Inside(WorldToVolume(p))) return 0.; return PhaseHG(wi, wo, g); }