コード例 #1
0
ファイル: Bsdf.cs プロジェクト: MassVOiD/aether
        public Spectrum SampleF(Vector woW, out Vector wiW, BsdfSample bsdfSample,
                                out float pdf, BxdfType flags = BxdfType.All)
        {
            BxdfType sampledType;

            return(SampleF(woW, out wiW, bsdfSample, out pdf, out sampledType, flags));
        }
コード例 #2
0
        public double Pdf(Vector3D woWorld, Vector3D wiWorld, BxdfType flags = BxdfType.All)
        {
            //ProfilePhase pp(Prof::BSDFPdf);
            if (_nBxDFs == 0)
            {
                return(0.0);
            }

            Vector3D wo = WorldToLocal(woWorld);
            Vector3D wi = WorldToLocal(wiWorld);

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

            double pdf           = 0.0;
            int    matchingComps = 0;

            for (int i = 0; i < _nBxDFs; ++i)
            {
                if (_bxdfs[i].MatchesFlags(flags))
                {
                    ++matchingComps;
                    pdf += _bxdfs[i].Pdf(wo, wi);
                }
            }

            double v = matchingComps > 0 ? pdf / matchingComps : 0.0;

            return(v);
        }
コード例 #3
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);
        }
コード例 #4
0
        public int NumComponents(BxdfType flags = BxdfType.All)
        {
            int num = 0;

            for (int i = 0; i < _nBxDFs; ++i)
            {
                if (_bxdfs[i].MatchesFlags(flags))
                {
                    ++num;
                }
            }

            return(num);
        }
コード例 #5
0
ファイル: Bsdf.cs プロジェクト: MassVOiD/aether
        public Spectrum Rho(Vector wo, Random rng, BxdfType flags = BxdfType.All, int sqrtSamples = 6)
        {
            int nSamples = sqrtSamples * sqrtSamples;
            var s1       = new float[2 * nSamples];

            SamplingUtilities.StratifiedSample2D(s1, sqrtSamples, sqrtSamples, rng);
            Spectrum ret = Spectrum.CreateBlack();

            foreach (var bxdf in _bxdfs)
            {
                if (bxdf.MatchesFlags(flags))
                {
                    ret += bxdf.Rho(wo, nSamples, s1);
                }
            }
            return(ret);
        }
コード例 #6
0
        public Spectrum SpecularReflect(
            RayDifferential ray,
            SurfaceInteraction isect,
            Scene scene,
            Sampler sampler,
            int depth)
        {
            // Compute specular reflection direction _wi_ and BSDF value
            Vector3D wo   = isect.Wo;
            BxdfType type = BxdfType.Reflection | BxdfType.Specular;
            Spectrum f    = isect.Bsdf.Sample_f(wo, out Vector3D wi, sampler.Get2D(), out double pdf, out BxdfType sampledType, type);

            // Return contribution of specular reflection
            Normal3D ns = isect.ShadingN;

            if (pdf > 0.0 && !f.IsBlack() && wi.AbsDot(ns) != 0.0)
            {
                // Compute ray differential _rd_ for specular reflection
                RayDifferential rd = new RayDifferential(isect.SpawnRay(wi));
                if (ray.HasDifferentials)
                {
                    rd.HasDifferentials = true;
                    rd.RxOrigin         = isect.P + isect.Dpdx.ToPoint3D();
                    rd.RyOrigin         = isect.P + isect.Dpdy.ToPoint3D();
                    // Compute differential reflected directions
                    Normal3D dndx = isect.ShadingDndu * isect.Dudx +
                                    isect.ShadingDndv * isect.Dvdx;
                    Normal3D dndy = isect.ShadingDndu * isect.Dudy +
                                    isect.ShadingDndv * isect.Dvdy;
                    Vector3D dwodx = -ray.RxDirection - wo,
                             dwody = -ray.RyDirection - wo;
                    double dDNdx   = dwodx.Dot(ns) + wo.Dot(dndx);
                    double dDNdy   = dwody.Dot(ns) + wo.Dot(dndy);
                    rd.RxDirection =
                        wi - dwodx + 2.0 * (wo.Dot(ns) * dndx + dDNdx * ns).ToVector3D();
                    rd.RyDirection =
                        wi - dwody + 2.0 * (wo.Dot(ns) * dndy + dDNdy * ns).ToVector3D();
                }
                return(f * Li(rd, scene, sampler, depth + 1) * wi.AbsDot(ns) /
                       pdf);
            }
            else
            {
                return(Spectrum.Create(0.0));
            }
        }
コード例 #7
0
        public Spectrum rho(
            int nSamples,
            IEnumerable <Point2D> samples1,
            IEnumerable <Point2D> samples2,
            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(nSamples, samples1, samples2);
                }
            }

            return(ret);
        }
コード例 #8
0
ファイル: Bxdf.cs プロジェクト: MarkZuber/pbrtnet
        public virtual Spectrum Sample_f(
            Vector3D wo,
            out Vector3D wi,
            Point2D sample,
            out double pdf,
            out BxdfType sampledType)
        {
            sampledType = BxdfType.None;

            // Cosine-sample the hemisphere, flipping the direction if necessary
            wi = Sampling.CosineSampleHemisphere(sample);
            if (wo.Z < 0.0)
            {
                wi = new Vector3D(wi.X, wi.Y, -wi.Z);
            }

            pdf = Pdf(wo, wi);
            return(f(wo, wi));
        }
コード例 #9
0
ファイル: Bsdf.cs プロジェクト: MassVOiD/aether
        public float Pdf(Vector woW, Vector wiW, BxdfType flags = BxdfType.All)
        {
            if (_bxdfs.Count == 0)
            {
                return(0.0f);
            }
            Vector wo = WorldToLocal(woW), wi = WorldToLocal(wiW);
            float  pdf           = 0.0f;
            int    matchingComps = 0;

            foreach (var bxdf in _bxdfs)
            {
                if (bxdf.MatchesFlags(flags))
                {
                    ++matchingComps;
                    pdf += bxdf.Pdf(wo, wi);
                }
            }
            float v = matchingComps > 0 ? pdf / matchingComps : 0.0f;

            return(v);
        }
コード例 #10
0
ファイル: Bsdf.cs プロジェクト: MassVOiD/aether
        public Spectrum F(Vector woW, Vector wiW, BxdfType flags = BxdfType.All)
        {
            Vector wi = WorldToLocal(wiW), wo = WorldToLocal(woW);

            if (Vector.Dot(wiW, _ng) * Vector.Dot(woW, _ng) > 0) // ignore BTDFs
            {
                flags &= ~BxdfType.Transmission;
            }
            else // ignore BRDFs
            {
                flags &= ~BxdfType.Reflection;
            }
            Spectrum f = Spectrum.CreateBlack();

            foreach (var bxdf in _bxdfs)
            {
                if (bxdf.MatchesFlags(flags))
                {
                    f += bxdf.F(wo, wi);
                }
            }
            return(f);
        }
コード例 #11
0
ファイル: Bsdf.cs プロジェクト: modulexcite/aether
 public float Pdf(Vector woW, Vector wiW, BxdfType flags = BxdfType.All)
 {
     if (_bxdfs.Count == 0)
         return 0.0f;
     Vector wo = WorldToLocal(woW), wi = WorldToLocal(wiW);
     float pdf = 0.0f;
     int matchingComps = 0;
     foreach (var bxdf in _bxdfs)
         if (bxdf.MatchesFlags(flags))
         {
             ++matchingComps;
             pdf += bxdf.Pdf(wo, wi);
         }
     float v = matchingComps > 0 ? pdf / matchingComps : 0.0f;
     return v;
 }
コード例 #12
0
ファイル: Bxdf.cs プロジェクト: MarkZuber/pbrtnet
 public bool MatchesFlags(BxdfType t)
 {
     return((Type & t) == Type);
 }
コード例 #13
0
ファイル: Bxdf.cs プロジェクト: MarkZuber/pbrtnet
 protected Bxdf(BxdfType type)
 {
     Type = type;
 }
コード例 #14
0
ファイル: Bsdf.cs プロジェクト: modulexcite/aether
 public Spectrum F(Vector woW, Vector wiW, BxdfType flags = BxdfType.All)
 {
     Vector wi = WorldToLocal(wiW), wo = WorldToLocal(woW);
     if (Vector.Dot(wiW, _ng) * Vector.Dot(woW, _ng) > 0) // ignore BTDFs
         flags &= ~BxdfType.Transmission;
     else // ignore BRDFs
         flags &= ~BxdfType.Reflection;
     Spectrum f = Spectrum.CreateBlack();
     foreach (var bxdf in _bxdfs)
         if (bxdf.MatchesFlags(flags))
             f += bxdf.F(wo, wi);
     return f;
 }
コード例 #15
0
ファイル: Bxdf.cs プロジェクト: MassVOiD/aether
 public bool MatchesFlags(BxdfType flags)
 {
     return((Type & flags) == Type);
 }
コード例 #16
0
ファイル: Bsdf.cs プロジェクト: MassVOiD/aether
        public Spectrum SampleF(Vector woW, out Vector wiW, BsdfSample bsdfSample,
                                out float pdf, out BxdfType sampledType, BxdfType flags = BxdfType.All)
        {
            // Choose which _BxDF_ to sample
            int matchingComps = NumComponents(flags);

            if (matchingComps == 0)
            {
                wiW         = Vector.Zero;
                pdf         = 0.0f;
                sampledType = 0;
                return(Spectrum.CreateBlack());
            }
            int which = Math.Min(
                MathUtility.Floor(bsdfSample.UComponent * matchingComps),
                matchingComps - 1);
            Bxdf bxdf  = null;
            int  count = which;

            foreach (var eachBxdf in _bxdfs)
            {
                if (eachBxdf.MatchesFlags(flags) && count-- == 0)
                {
                    bxdf = eachBxdf;
                    break;
                }
            }
            Debug.Assert(bxdf != null);

            // Sample chosen _BxDF_
            Vector wo = WorldToLocal(woW);
            Vector wi;

            pdf = 0.0f;
            Spectrum f = bxdf.SampleF(wo, out wi, bsdfSample.UDir0, bsdfSample.UDir1, out pdf);

            if (pdf == 0.0f)
            {
                wiW         = Vector.Zero;
                sampledType = 0;
                return(Spectrum.CreateBlack());
            }
            sampledType = bxdf.Type;
            wiW         = LocalToWorld(wi);

            // Compute overall PDF with all matching _BxDF_s
            if (!bxdf.Type.HasFlag(BxdfType.Specular) && matchingComps > 1)
            {
                foreach (var eachBxdf in _bxdfs)
                {
                    if (eachBxdf != bxdf && eachBxdf.MatchesFlags(flags))
                    {
                        pdf += bxdf.Pdf(wo, wi);
                    }
                }
            }
            if (matchingComps > 1)
            {
                pdf /= matchingComps;
            }

            // Compute value of BSDF for sampled direction
            if (!bxdf.Type.HasFlag(BxdfType.Specular))
            {
                f = Spectrum.CreateBlack();
                if (Vector.Dot(wiW, _ng) * Vector.Dot(woW, _ng) > 0) // ignore BTDFs
                {
                    flags &= ~BxdfType.Transmission;
                }
                else // ignore BRDFs
                {
                    flags &= ~BxdfType.Reflection;
                }
                foreach (var eachBxdf in _bxdfs)
                {
                    if (eachBxdf.MatchesFlags(flags))
                    {
                        f += eachBxdf.F(wo, wi);
                    }
                }
            }
            return(f);
        }
コード例 #17
0
ファイル: Bsdf.cs プロジェクト: modulexcite/aether
 public Spectrum Rho(Vector wo, Random rng, BxdfType flags = BxdfType.All, int sqrtSamples = 6)
 {
     int nSamples = sqrtSamples * sqrtSamples;
     var s1 = new float[2 * nSamples];
     SamplingUtilities.StratifiedSample2D(s1, sqrtSamples, sqrtSamples, rng);
     Spectrum ret = Spectrum.CreateBlack();
     foreach (var bxdf in _bxdfs)
         if (bxdf.MatchesFlags(flags))
             ret += bxdf.Rho(wo, nSamples, s1);
     return ret;
 }
コード例 #18
0
ファイル: Bsdf.cs プロジェクト: modulexcite/aether
 public Spectrum SampleF(Vector woW, out Vector wiW, BsdfSample bsdfSample,
     out float pdf, BxdfType flags = BxdfType.All)
 {
     BxdfType sampledType;
     return SampleF(woW, out wiW, bsdfSample, out pdf, out sampledType, flags);
 }
コード例 #19
0
ファイル: Bsdf.cs プロジェクト: MassVOiD/aether
 public int NumComponents(BxdfType flags)
 {
     return(_bxdfs.Count(x => x.MatchesFlags(flags)));
 }
コード例 #20
0
ファイル: Bsdf.cs プロジェクト: modulexcite/aether
 public int NumComponents(BxdfType flags)
 {
     return _bxdfs.Count(x => x.MatchesFlags(flags));
 }
コード例 #21
0
ファイル: Bsdf.cs プロジェクト: modulexcite/aether
        public Spectrum SampleF(Vector woW, out Vector wiW, BsdfSample bsdfSample,
            out float pdf, out BxdfType sampledType, BxdfType flags = BxdfType.All)
        {
            // Choose which _BxDF_ to sample
            int matchingComps = NumComponents(flags);
            if (matchingComps == 0)
            {
                wiW = Vector.Zero;
                pdf = 0.0f;
                sampledType = 0;
                return Spectrum.CreateBlack();
            }
            int which = Math.Min(
                MathUtility.Floor(bsdfSample.UComponent * matchingComps),
                matchingComps - 1);
            Bxdf bxdf = null;
            int count = which;
            foreach (var eachBxdf in _bxdfs)
                if (eachBxdf.MatchesFlags(flags) && count-- == 0)
                {
                    bxdf = eachBxdf;
                    break;
                }
            Debug.Assert(bxdf != null);

            // Sample chosen _BxDF_
            Vector wo = WorldToLocal(woW);
            Vector wi;
            pdf = 0.0f;
            Spectrum f = bxdf.SampleF(wo, out wi, bsdfSample.UDir0, bsdfSample.UDir1, out pdf);
            if (pdf == 0.0f)
            {
                wiW = Vector.Zero;
                sampledType = 0;
                return Spectrum.CreateBlack();
            }
            sampledType = bxdf.Type;
            wiW = LocalToWorld(wi);

            // Compute overall PDF with all matching _BxDF_s
            if (!bxdf.Type.HasFlag(BxdfType.Specular) && matchingComps > 1)
                foreach (var eachBxdf in _bxdfs)
                    if (eachBxdf != bxdf && eachBxdf.MatchesFlags(flags))
                        pdf += bxdf.Pdf(wo, wi);
            if (matchingComps > 1)
                pdf /= matchingComps;

            // Compute value of BSDF for sampled direction
            if (!bxdf.Type.HasFlag(BxdfType.Specular))
            {
                f = Spectrum.CreateBlack();
                if (Vector.Dot(wiW, _ng) * Vector.Dot(woW, _ng) > 0) // ignore BTDFs
                    flags &= ~BxdfType.Transmission;
                else // ignore BRDFs
                    flags &= ~BxdfType.Reflection;
                foreach (var eachBxdf in _bxdfs)
                    if (eachBxdf.MatchesFlags(flags))
                        f += eachBxdf.F(wo, wi);
            }
            return f;
        }
コード例 #22
0
ファイル: Bxdf.cs プロジェクト: modulexcite/aether
 public bool MatchesFlags(BxdfType flags)
 {
     return (Type & flags) == Type;
 }
コード例 #23
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);
        }
コード例 #24
0
ファイル: Bxdf.cs プロジェクト: modulexcite/aether
 protected Bxdf(BxdfType type)
 {
     Type = type;
 }