示例#1
0
文件: Bxdf.cs 项目: MassVOiD/aether
        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));
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }