示例#1
0
 public void Add(Bxdf b)
 {
     // todo: CHECK_LT(_nBxDFs, MaxBxDFs);
     _bxdfs[_nBxDFs++] = b;
 }
示例#2
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);
        }