void SpotLight::Pdf_Le(const Ray &ray, const Normal3f &, Float *pdfPos, Float *pdfDir) const { *pdfPos = 0; *pdfDir = (CosTheta(WorldToLight(ray.d)) >= cosTotalWidth) ? UniformConePdf(cosTotalWidth) : 0; }
void ProjectionLight::Pdf_Le(const Ray &ray, const Normal3f &, Float *pdfPos, Float *pdfDir) const { ProfilePhase _(Prof::LightPdf); *pdfPos = 0.f; *pdfDir = (CosTheta(WorldToLight(ray.d)) >= cosTotalWidth) ? UniformConePdf(cosTotalWidth) : 0; }
Float InfiniteAreaLight::Pdf_Li(const Interaction &, const Vector3f &w) const { Vector3f wi = WorldToLight(w); Float theta = SphericalTheta(wi), phi = SphericalPhi(wi); Float sinTheta = std::sin(theta); if (sinTheta == 0) return 0; return distribution->Pdf(Point2f(phi * Inv2Pi, theta * InvPi)) / (2 * Pi * Pi * sinTheta); }
Spectrum Scale(const Vector &w) const { Vector wp = Normalize(WorldToLight(w)); swap(wp.y, wp.z); float theta = SphericalTheta(wp); float phi = SphericalPhi(wp); float s = phi * INV_TWOPI, t = theta * INV_PI; return mipmap ? mipmap->Lookup(s, t) : 1.f; }
void InfiniteAreaLight::Pdf(const Ray &ray, const Normal3f &, Float *pdfPos, Float *pdfDir) const { Vector3f d = -WorldToLight(ray.d); Float theta = std::acos(d.z), phi = std::atan2(d.y, d.x); Point2f uv(phi * Inv2Pi, theta * InvPi); Float mapPdf = distribution->Pdf(uv); *pdfDir = mapPdf / (2 * Pi * Pi * std::sin(theta)); *pdfPos = 1 / (Pi * worldRadius * worldRadius); }
void InfiniteAreaLight::Pdf_Le(const Ray &ray, const Normal3f &, Float *pdfPos, Float *pdfDir) const { Vector3f d = -WorldToLight(ray.d); Float theta = SphericalTheta(d), phi = SphericalPhi(d); Point2f uv(phi * Inv2Pi, theta * InvPi); Float mapPdf = distribution->Pdf(uv); *pdfDir = mapPdf / (2 * Pi * Pi * std::sin(theta)); *pdfPos = 1 / (Pi * worldRadius * worldRadius); }
Float SpotLight::Falloff(const Vector3f &w) const { Vector3f wl = Normalize(WorldToLight(w)); Float cosTheta = wl.z; if (cosTheta < cosTotalWidth) return 0; if (cosTheta > cosFalloffStart) return 1; // Compute falloff inside spotlight cone Float delta = (cosTheta - cosTotalWidth) / (cosFalloffStart - cosTotalWidth); return (delta * delta) * (delta * delta); }
float SpotLight::Falloff(const Vector &w) const { Vector wl = Normalize(WorldToLight(w)); float costheta = wl.z; if (costheta < cosTotalWidth) return 0.; if (costheta > cosFalloffStart) return 1.; // Compute falloff inside spotlight cone float delta = (costheta - cosTotalWidth) / (cosFalloffStart - cosTotalWidth); return delta*delta*delta*delta; }
Spectrum ProjectionLight::Projection(const Vector3f &w) const { Vector3f wl = WorldToLight(w); // Discard directions behind projection light if (wl.z < hither) return 0; // Project point onto projection plane and compute light Point3f p = lightProjection(Point3f(wl.x, wl.y, wl.z)); if (!Inside(Point2f(p.x, p.y), screenBounds)) return 0.f; if (!projectionMap) return 1; Point2f st = Point2f(screenBounds.Offset(Point2f(p.x, p.y))); return Spectrum(projectionMap->Lookup(st), SpectrumType::Illuminant); }
float InfiniteAreaLightIS::Pdf(const Point &, const Vector &w) const { Vector wi = WorldToLight(w); float theta = SphericalTheta(wi), phi = SphericalPhi(wi); int u = Clamp(Float2Int(phi * INV_TWOPI * uDistrib->count), 0, uDistrib->count-1); int v = Clamp(Float2Int(theta * INV_PI * vDistribs[u]->count), 0, vDistribs[u]->count-1); return (uDistrib->func[u] * vDistribs[u]->func[v]) / (uDistrib->funcInt * vDistribs[u]->funcInt) * 1.f / (2.f * M_PI * M_PI * sin(theta)); }
Spectrum InfiniteAreaLightIS::Le(const RayDifferential &r) const { Vector w = r.d; // Compute infinite light radiance for direction Spectrum L = Lbase; if (radianceMap != NULL) { Vector wh = Normalize(WorldToLight(w)); float s = SphericalPhi(wh) * INV_TWOPI; float t = SphericalTheta(wh) * INV_PI; L *= radianceMap->Lookup(s, t); } return L; }
Spectrum ProjectionLight::Projection(const Vector &w) const { Vector wl = WorldToLight(w); // Discard directions behind projection light if (wl.z < hither) return 0.; // Project point onto projection plane and compute light Point Pl = lightProjection(Point(wl.x, wl.y, wl.z)); if (Pl.x < screenX0 || Pl.x > screenX1 || Pl.y < screenY0 || Pl.y > screenY1) return 0.; if (!projectionMap) return 1; float s = (Pl.x - screenX0) / (screenX1 - screenX0); float t = (Pl.y - screenY0) / (screenY1 - screenY0); return Spectrum(projectionMap->Lookup(s, t), SPECTRUM_ILLUMINANT); }
Vector ProjectionLight::Projection(const Point& p) const { Vector w = Normalize(lightPos - p); Vector wl = WorldToLight(w); // Discard directions behind projection light if (wl.z < hither) return Vector(); // Project point onto projection plane and compute light Point Pl = lightProjection(Point(wl.x, wl.y, wl.z)); if (Pl.x < screenX0 || Pl.x > screenX1 || Pl.y < screenY0 || Pl.y > screenY1) return Vector(); float s = (Pl.x - screenX0) / (screenX1 - screenX0); float t = (Pl.y - screenY0) / (screenY1 - screenY0); // change s,t to image coordinate int u = texture->cols - int(texture->cols * s); int v = int(texture->rows * t); cv::Vec3b texLight = texture->at<cv::Vec3b>(v, u); return Vector(float(texLight[0])/256.f, float(texLight[1])/256.f, float(texLight[2])/256.f); }
Spectrum InfiniteAreaLight::Le(const RayDifferential &ray) const { Vector3f w = Normalize(WorldToLight(ray.d)); Point2f st(SphericalPhi(w) * Inv2Pi, SphericalTheta(w) * InvPi); return Spectrum(Lmap->Lookup(st), SpectrumType::Illuminant); }