Exemple #1
0
        public bool IntersectTr(Ray ray, Sampler sampler, out SurfaceInteraction isect, out Spectrum transmittance)
        {
            transmittance = Spectrum.Create(1.0);
            while (true)
            {
                bool hitSurface = Intersect(ray, out isect);
                // Accumulate beam transmittance for ray segment
                if (ray.Medium != null)
                {
                    transmittance *= ray.Medium.Tr(ray, sampler);
                }

                // Initialize next ray segment or terminate transmittance computation
                if (!hitSurface)
                {
                    return(false);
                }

                if (isect.Primitive.GetMaterial() != null)
                {
                    return(true);
                }

                ray = isect.SpawnRay(ray.Direction);
            }
        }
Exemple #2
0
        public Spectrum f(Vector3D woW, Vector3D wiW, BxdfType flags = BxdfType.All)
        {
            // ProfilePhase pp(Prof::BSDFEvaluation);
            Vector3D wi = WorldToLocal(wiW), wo = WorldToLocal(woW);

            if (wo.Z == 0.0)
            {
                return(Spectrum.Create(0.0));
            }

            bool     reflect = wiW.Dot(_ng) * woW.Dot(_ng) > 0.0;
            Spectrum f       = Spectrum.Create(0.0);

            for (int i = 0; i < _nBxDFs; ++i)
            {
                if (_bxdfs[i].MatchesFlags(flags) &&
                    ((reflect && ((_bxdfs[i].Type & BxdfType.Reflection) == BxdfType.Reflection)) ||
                     (!reflect && ((_bxdfs[i].Type & BxdfType.Transmission) == BxdfType.Transmission))))
                {
                    f += _bxdfs[i].f(wo, wi);
                }
            }

            return(f);
        }
        public Spectrum Tr(Scene scene, Sampler sampler)
        {
            Ray      ray = new Ray(P0.SpawnRayTo(P1));
            Spectrum Tr  = Spectrum.Create(1.0);

            while (true)
            {
                SurfaceInteraction isect;
                bool hitSurface = scene.Intersect(ray, out isect);
                // Handle opaque surface along ray's path
                if (hitSurface && isect.Primitive.GetMaterial() != null)
                {
                    return(Spectrum.Create(0.0));
                }

                // Update transmittance for current ray segment
                if (ray.Medium != null)
                {
                    Tr *= ray.Medium.Tr(ray, sampler);
                }

                // Generate next ray segment or return final transmittance
                if (!hitSurface)
                {
                    break;
                }

                ray = isect.SpawnRayTo(P1);
            }
            return(Tr);
        }
Exemple #4
0
        public Spectrum rho(Vector3D wo, int nSamples, IEnumerable <Point2D> samples, BxdfType flags = BxdfType.All)
        {
            Spectrum ret = Spectrum.Create(0.0);

            for (int i = 0; i < _nBxDFs; ++i)
            {
                if (_bxdfs[i].MatchesFlags(flags))
                {
                    ret += _bxdfs[i].rho(wo, nSamples, samples);
                }
            }

            return(ret);
        }
Exemple #5
0
        public virtual Spectrum rho(Vector3D wo, int nSamples, IEnumerable <Point2D> samples)
        {
            Spectrum r = Spectrum.Create(0.0);

            foreach (Point2D sample in samples)
            {
                // Estimate one term of $\rho_\roman{hd}$
                Spectrum f = Sample_f(wo, out Vector3D wi, sample, out double pdf, out BxdfType sampledType);
                if (pdf > 0)
                {
                    r += f * Reflection.AbsCosTheta(wi) / pdf;
                }
            }
            return(r / nSamples);
        }
Exemple #6
0
        public virtual Spectrum rho(int nSamples, IEnumerable <Point2D> samples1, IEnumerable <Point2D> samples2)
        {
            var      u1 = samples1.ToList();
            var      u2 = samples2.ToList();
            Spectrum r  = Spectrum.Create(0.0);

            for (int i = 0; i < nSamples; ++i)
            {
                // Estimate one term of $\rho_\roman{hh}$
                Vector3D wo   = Sampling.UniformSampleHemisphere(u1[i]);
                double   pdfo = Sampling.UniformHemispherePdf();
                Spectrum f    = Sample_f(wo, out Vector3D wi, u2[i], out double pdfi, out BxdfType sampledType);
                if (pdfi > 0)
                {
                    r += f * Reflection.AbsCosTheta(wi) * Reflection.AbsCosTheta(wo) / (pdfo * pdfi);
                }
            }
            return(r / (Math.PI * nSamples));
        }
Exemple #7
0
 public virtual Spectrum Le(RayDifferential r)
 {
     return(Spectrum.Create(0.0));
 }
Exemple #8
0
        public Spectrum Sample_f(
            Vector3D woWorld,
            out Vector3D wiWorld,
            Point2D u,
            out double pdf,
            out BxdfType sampledType,
            BxdfType type = BxdfType.All)
        {
            // ProfilePhase pp(Prof::BSDFSampling);
            // Choose which _BxDF_ to sample
            int matchingComps = NumComponents(type);

            if (matchingComps == 0)
            {
                pdf         = 0.0;
                sampledType = BxdfType.None;
                wiWorld     = new Vector3D();
                return(Spectrum.Create(0.0));
            }

            int comp = Math.Min(Convert.ToInt32(Math.Floor(u[0] * matchingComps)), matchingComps - 1);

            // Get _BxDF_ pointer for chosen component
            Bxdf bxdf  = null;
            int  count = comp;

            for (int i = 0; i < _nBxDFs; ++i)
            {
                if (_bxdfs[i].MatchesFlags(type) && count-- == 0)
                {
                    bxdf = _bxdfs[i];
                    break;
                }
            }

            //CHECK(bxdf != nullptr);
            //VLOG(2) << "BSDF::Sample_f chose comp = " << comp << " / matching = " <<
            //    matchingComps << ", bxdf: " << bxdf->ToString();

            // Remap _BxDF_ sample _u_ to $[0,1)^2$
            Point2D uRemapped = new Point2D(Math.Min(u[0] * matchingComps - comp, PbrtMath.OneMinusEpsilon),
                                            u[1]);

            // Sample chosen _BxDF_
            Vector3D wi, wo = WorldToLocal(woWorld);

            if (wo.Z == 0)
            {
                wiWorld     = new Vector3D();
                pdf         = 0.0;
                sampledType = BxdfType.None;
                return(Spectrum.Create(0.0));
            }

            pdf         = 0.0;
            sampledType = bxdf.Type;

            Spectrum f = bxdf.Sample_f(wo, out wi, uRemapped, out pdf, out sampledType);

            //VLOG(2) << "For wo = " << wo << ", sampled f = " << f << ", pdf = "
            //        << *pdf << ", ratio = " << ((*pdf > 0) ? (f / *pdf) : Spectrum(0.))
            //        << ", wi = " << wi;
            if (pdf == 0.0)
            {
                sampledType = BxdfType.None;
                wiWorld     = new Vector3D();
                return(Spectrum.Create(0.0));
            }
            wiWorld = LocalToWorld(wi);

            // Compute overall PDF with all matching _BxDF_s
            if ((bxdf.Type & BxdfType.Specular) != BxdfType.Specular && matchingComps > 1)
            {
                for (int i = 0; i < _nBxDFs; ++i)
                {
                    if (_bxdfs[i] != bxdf && _bxdfs[i].MatchesFlags(type))
                    {
                        pdf += _bxdfs[i].Pdf(wo, wi);
                    }
                }
            }

            if (matchingComps > 1)
            {
                pdf /= matchingComps;
            }

            // Compute value of BSDF for sampled direction
            if ((bxdf.Type & BxdfType.Specular) != BxdfType.Specular)
            {
                bool reflect = wiWorld.Dot(_ng) * woWorld.Dot(_ng) > 0.0;
                f = Spectrum.Create(0.0);
                for (int i = 0; i < _nBxDFs; ++i)
                {
                    if (_bxdfs[i].MatchesFlags(type) &&
                        ((reflect && ((_bxdfs[i].Type & BxdfType.Reflection) == BxdfType.Reflection) ||
                          (!reflect && ((_bxdfs[i].Type & BxdfType.Transmission) == BxdfType.Transmission)))))
                    {
                        f += _bxdfs[i].f(wo, wi);
                    }
                }
            }
            //VLOG(2) << "Overall f = " << f << ", pdf = " << *pdf << ", ratio = "
            //        << ((*pdf > 0) ? (f / *pdf) : Spectrum(0.));
            return(f);
        }