Esempio n. 1
0
        public virtual double Pdf(SurfaceInteraction si, Vector3 wi)
        {
            // Intersect sample ray with area light geometry
            Ray ray = si.SpawnRay(wi);

            (double?tHit, SurfaceInteraction isectLight) = Intersect(ray);

            if (!tHit.HasValue)
            {
                return(0);
            }

            // Convert area measure to solid angle measure
            double pdf = (si.Point - isectLight.Point).LengthSquared() / (Vector3.AbsDot(isectLight.Normal, -wi) * Area());

            if (double.IsInfinity(pdf))
            {
                pdf = 0;
            }
            return(pdf);
        }
Esempio n. 2
0
        public Spectrum Li(Ray r, Scene s)
        {
            Spectrum L = Spectrum.ZeroSpectrum;
            Spectrum B = Spectrum.Create(1);

            int nbounces = 0;

            while (nbounces < 20)
            {
                SurfaceInteraction isect = null;

                //Get the object the ray intersected with
                isect = s.Intersect(r).Item2;

                //If the ray hasn't hit anything return 0
                if (isect == null)
                {
                    break;
                }

                Vector3 wo = isect.Wo;//-r.d;
                //If the ray hit a light, take its emission
                if (isect.Obj is Light)
                {
                    if (nbounces == 0)
                    {
                        L = B * isect.Le(wo);
                    }
                    break;
                }

                //Create a light ray from the intersection point and add its emission
                Spectrum Ld = Light.UniformSampleOneLight(isect, s);
                L = L.AddTo(B * Ld);


                //Get the materials value at this point
                (Spectrum f, Vector3 wi, double pr, bool specular) = (isect.Obj as Shape).BSDF.Sample_f(wo, isect);

                if (!specular)
                {
                    B = B * f * Utils.AbsCosTheta(wi) / pr;
                }


                //Spawn a new ray from the intersection
                r = isect.SpawnRay(wi);

                if (nbounces > 3)
                {
                    double q = 1.0 - B.Max();
                    if (ThreadSafeRandom.NextDouble() < q)
                    {
                        break;
                    }
                    B = B / (1 - q);
                }
                nbounces++;
            }

            return(L);
        }