/// <inheritdoc /> public override void Pdf_We(Ray ray, out double pdfPos, out double pdfDir) { // Interpolate camera matrix and fail if $\w{}$ is not forward-facing CameraToWorld.Interpolate(ray.Time, out Transform c2w); double cosTheta = ray.Direction.Dot(c2w.ExecuteTransform(new Vector3D(0.0, 0.0, 1.0))); if (cosTheta <= 0) { pdfPos = pdfDir = 0.0; return; } // Map ray $(\p{}, \w{})$ onto the raster grid Point3D pFocus = ray.AtPoint((LensRadius > 0.0 ? FocalDistance : 1.0) / cosTheta); Point3D pRaster = RasterToCamera.Inverse().ExecuteTransform(c2w.Inverse().ExecuteTransform(pFocus)); // Return zero probability for out of bounds points Bounds2I sampleBounds = Film.GetSampleBounds(); if (pRaster.X < sampleBounds.MinPoint.X || pRaster.X >= sampleBounds.MaxPoint.X || pRaster.Y < sampleBounds.MinPoint.Y || pRaster.Y >= sampleBounds.MaxPoint.Y) { pdfPos = pdfDir = 0.0; return; } // Compute lens area of perspective camera double lensArea = LensRadius != 0.0 ? (Math.PI * LensRadius * LensRadius) : 1.0; pdfPos = 1.0 / lensArea; pdfDir = 1.0 / (_a * cosTheta * cosTheta * cosTheta); }
/// <inheritdoc /> public override Spectrum We(Ray ray, out Point2D pRaster2) { // Interpolate camera matrix and check if $\w{}$ is forward-facing CameraToWorld.Interpolate(ray.Time, out Transform c2w); double cosTheta = ray.Direction.Dot(c2w.ExecuteTransform(new Vector3D(0.0, 0.0, 1.0))); if (cosTheta <= 0.0) { pRaster2 = null; return(Spectrum.Create(0.0)); } // Map ray $(\p{}, \w{})$ onto the raster grid Point3D pFocus = ray.AtPoint((LensRadius > 0.0 ? FocalDistance : 1.0) / cosTheta); Point3D pRaster = RasterToCamera.ExecuteTransform(c2w.Inverse().ExecuteTransform(pFocus)); //Point3D pRaster = Inverse(RasterToCamera)(Inverse(c2w.Inverse)(pFocus)); // Return raster position if requested pRaster2 = new Point2D(pRaster.X, pRaster.Y); // Return zero importance for out of bounds points Bounds2I sampleBounds = Film.GetSampleBounds(); if (pRaster.X < sampleBounds.MinPoint.X || pRaster.Z >= sampleBounds.MaxPoint.X || pRaster.Y < sampleBounds.MinPoint.Y || pRaster.Y >= sampleBounds.MaxPoint.Y) { return(Spectrum.Create(0.0)); } // Compute lens area of perspective camera double lensArea = LensRadius != 0.0 ? (Math.PI * LensRadius * LensRadius) : 1.0; // Return importance for point on image plane double cos2Theta = cosTheta * cosTheta; return(Spectrum.Create(1.0 / (_a * lensArea * cos2Theta * cos2Theta))); }