public virtual Spectrum Rho(int numSamples, float[] samples1, float[] samples2) { Spectrum r = Spectrum.CreateBlack(); for (int i = 0; i < numSamples; ++i) { // Estimate one term of $\rho_\roman{hh}$ Vector wo, wi; wo = MonteCarloUtilities.UniformSampleHemisphere(samples1[2 * i], samples1[2 * i + 1]); float pdf_o = MathUtility.InvTwoPi, pdf_i; Spectrum f = SampleF(wo, out wi, samples2[2 * i], samples2[2 * i + 1], out pdf_i); if (pdf_i > 0.0f) { r += f * ReflectionUtilities.AbsCosTheta(ref wi) * ReflectionUtilities.AbsCosTheta(ref wo) / (pdf_o * pdf_i); } } return(r / (MathUtility.Pi * numSamples)); }
public override Spectrum SampleL(Scene scene, LightSample ls, float u1, float u2, float time, out Ray ray, out Normal ns, out float pdf) { // Choose point on disk oriented toward infinite light direction Point worldCenter; float worldRadius; scene.WorldBound.BoundingSphere(out worldCenter, out worldRadius); Vector v1, v2; Vector.CoordinateSystem(_direction, out v1, out v2); float d1, d2; MonteCarloUtilities.ConcentricSampleDisk(ls.UPos0, ls.UPos1, out d1, out d2); Point Pdisk = worldCenter + worldRadius * (d1 * v1 + d2 * v2); // Set ray origin and direction for infinite light ray ray = new Ray(Pdisk + worldRadius * _direction, -_direction, 0.0f, float.PositiveInfinity, time); ns = (Normal)ray.Direction; pdf = 1.0f / (MathUtility.Pi * worldRadius * worldRadius); return(_radiance); }
public override Point Sample(Point p, float u1, float u2, out Normal ns) { // Compute coordinate system for sphere sampling Point Pcenter = ObjectToWorld.TransformPoint(Point.Zero); Vector wc = Vector.Normalize(Pcenter - p); Vector wcX, wcY; Vector.CoordinateSystem(wc, out wcX, out wcY); // Sample uniformly on sphere if $\pt{}$ is inside it if (Point.DistanceSquared(p, Pcenter) - _radius * _radius < 1e-4f) { return(Sample(u1, u2, out ns)); } // Sample sphere uniformly inside subtended cone float sinThetaMax2 = _radius * _radius / Point.DistanceSquared(p, Pcenter); float cosThetaMax = MathUtility.Sqrt(Math.Max(0.0f, 1.0f - sinThetaMax2)); DifferentialGeometry dgSphere; float thit, rayEpsilon; Point ps; Ray r = new Ray(p, MonteCarloUtilities.UniformSampleCone(u1, u2, cosThetaMax, ref wcX, ref wcY, ref wc), 1e-3f); if (!TryIntersect(r, out thit, out rayEpsilon, out dgSphere)) { thit = Vector.Dot(Pcenter - p, Vector.Normalize(r.Direction)); } ps = r.Evaluate(thit); ns = (Normal)Vector.Normalize(ps - Pcenter); if (ReverseOrientation) { ns *= -1.0f; } return(ps); }