예제 #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
파일: 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);
        }
예제 #3
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;
        }
예제 #4
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);
 }