Spectrum InfiniteAreaLight::Sample_Li(const Interaction &ref, const Point2f &u, Vector3f *wi, Float *pdf, VisibilityTester *vis) const { // Find $(u,v)$ sample coordinates in infinite light texture Float mapPdf; Point2f uv = distribution->SampleContinuous(u, &mapPdf); uv[0] -= (Float)0.5 / Lmap->Width(); uv[1] -= (Float)0.5 / Lmap->Height(); if (mapPdf == 0) return Spectrum(0.f); // Convert infinite light sample point to direction Float theta = uv[1] * Pi, phi = uv[0] * 2 * Pi; Float cosTheta = std::cos(theta), sinTheta = std::sin(theta); Float sinPhi = std::sin(phi), cosPhi = std::cos(phi); *wi = LightToWorld(Vector3f(sinTheta * cosPhi, sinTheta * sinPhi, cosTheta)); // Compute PDF for sampled infinite light direction *pdf = mapPdf / (2 * Pi * Pi * sinTheta); if (sinTheta == 0) *pdf = 0; // Return radiance value for infinite light direction *vis = VisibilityTester(ref, Interaction(ref.p + *wi * (2 * worldRadius), ref.time, mediumInterface)); return Spectrum(Lmap->Lookup(uv), SpectrumType::Illuminant); }
Spectrum SpotLight::Sample_Li(const Interaction &ref, const Point2f &u, Vector3f *wi, Float *pdf, VisibilityTester *vis) const { *wi = Normalize(pLight - ref.p); *pdf = 1.f; *vis = VisibilityTester(ref, Interaction(pLight, ref.time, medium)); return intensity * Falloff(-*wi) / DistanceSquared(pLight, ref.p); }
// GonioPhotometricLight Method Definitions Spectrum GonioPhotometricLight::Sample_L(const Interaction &ref, const Point2f &sample, Vector3f *wi, Float *pdf, VisibilityTester *vis) const { *wi = Normalize(pLight - ref.p); *pdf = 1.f; *vis = VisibilityTester(ref, Interaction(pLight, ref.time, medium)); return intensity * Scale(-*wi) / DistanceSquared(pLight, ref.p); }
Spectrum DistantLight::Sample_L(const Interaction &ref, const Point2f &sample, Vector3f *wi, Float *pdf, VisibilityTester *vis) const { *wi = wLight; *pdf = 1.f; Point3f pOutside = ref.p + wLight * (2 * worldRadius); *vis = VisibilityTester(ref, Interaction(pOutside, ref.time, medium)); return L; }
Spectrum ProjectionLight::Sample_Li(const Interaction &ref, const Point2f &u, Vector3f *wi, Float *pdf, VisibilityTester *vis) const { ProfilePhase _(Prof::LightSample); *wi = Normalize(pLight - ref.p); *pdf = 1; *vis = VisibilityTester(ref, Interaction(pLight, ref.time, mediumInterface)); return I * Projection(-*wi) / DistanceSquared(pLight, ref.p); }
Spectrum DiffuseAreaLight::Sample_Li(const Interaction &ref, const Point2f &u, Vector3f *wi, Float *pdf, VisibilityTester *vis) const { Interaction pShape = shape->Sample(ref, u); pShape.mediumInterface = mediumInterface; *wi = Normalize(pShape.p - ref.p); *pdf = shape->Pdf(ref, *wi); *vis = VisibilityTester(ref, pShape); return L(pShape, -*wi); }
Spectrum DiffuseAreaLight::Sample_Li(const Interaction &ref, const Point2f &u, Vector3f *wi, Float *pdf, VisibilityTester *vis) const { ProfilePhase _(Prof::LightSample); Interaction pShape = shape->Sample(ref, u, pdf); pShape.mediumInterface = mediumInterface; if (*pdf == 0 || (pShape.p - ref.p).LengthSquared() == 0) { *pdf = 0; return 0.f; } *wi = Normalize(pShape.p - ref.p); *vis = VisibilityTester(ref, pShape); return L(pShape, -*wi); }
Spectrum PerspectiveCamera::Sample_Wi(const Interaction &ref, const Point2f &u, Vector3f *wi, Float *pdf, Point2f *pRaster, VisibilityTester *vis) const { // Uniformly sample a lens interaction _lensIntr_ Point2f pLens = lensRadius * ConcentricSampleDisk(u); Point3f pLensWorld = CameraToWorld(ref.time, Point3f(pLens.x, pLens.y, 0)); Interaction lensIntr(pLensWorld, ref.time, medium); lensIntr.n = Normal3f(CameraToWorld(ref.time, Vector3f(0, 0, 1))); // Populate arguments and compute the importance value *vis = VisibilityTester(ref, lensIntr); *wi = lensIntr.p - ref.p; Float dist = wi->Length(); *wi /= dist; // Compute PDF for importance arriving at _ref_ // Compute lens area of perspective camera Float lensArea = lensRadius != 0 ? (Pi * lensRadius * lensRadius) : 1; *pdf = (dist * dist) / (AbsDot(lensIntr.n, *wi) * lensArea); return We(lensIntr, -*wi, pRaster); }