Example #1
0
        public float Pdf(Vector3 <float> woWorld, Vector3 <float> wiWorld, BxDFType type)
        {
            if (!bxdfs.Any())
            {
                return(0);
            }

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

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

            var matchingBxdfs = bxdfs.Where(b => b.Matches(type));
            var pdf           = 0f;

            foreach (var b in bxdfs)
            {
                pdf += b.Pdf(wo, wi);
            }

            var count = matchingBxdfs.Count();

            return(count > 0 ? pdf / count : 0);
        }
Example #2
0
 public int NumComponents(BxDFType flags)
 {
     int num = 0;
     for (int i = 0; i < nBxDFs; ++i)
         if (bxdfs[i].MatchesFlags (flags))
             ++num;
     return num;
 }
Example #3
0
        public void Sample(ref Vector wo, ref Normal N, ref Normal shadeN, float u0, float u1, float u2,float u3,
                           out BsdfSample sample, BxDFType type = BxDFType.AllTypes) {
            sample = new BsdfSample();
            var fl = type;
            int matchingComps = NumComponents(fl);
            if (matchingComps == 0) {
                sample.Pdf = 0f;
                sample.Wi = Vector.Zero;
                sample.Spectrum = new RgbSpectrum(0f).ToArray();
            }
            int which = (int)Math.Min((u0 * matchingComps),
                matchingComps - 1);
            BxDFBase bxdf = null;
            int count = which;
            for (int i = 0; i < Bxdfs.Length; ++i)
                if (Bxdfs[i].Type.HasFlag(fl))
                    if (count-- == 0) {
                        bxdf = Bxdfs[i];
                        break;
                    }
            Vector wi = new Vector();
            var pdf = 0f;
            bxdf.Sample(ref wo, ref N, ref shadeN, u1,  u2, u3, out sample, type);
            wi = sample.Wi;
            pdf = sample.Pdf;
            var sampled = bxdf.Type;
            if (pdf > 0f && pdf < MathLab.Epsilon) sample.Spectrum = new float[3]{0f,0f,0f};
            //if (sampledTy != null) sampledType = bxdf.Type;
            //wiW = LocalToWorld(wi);

            if ((!bxdf.Type.HasFlag(BxDFType.Specular)) && matchingComps > 1) {
                for (int i = 0; i < Bxdfs.Length; ++i) {
                    if (Bxdfs[i] != bxdf && (Bxdfs[i].Type.HasFlag(fl)))
                        pdf += Bxdfs[i].Pdf(ref wo, ref wi, fl);
                }
            }
            if (matchingComps > 1) pdf /= matchingComps;
            // Compute value of BSDF for sampled direction
            if (bxdf.Type.HasFlag(BxDFType.Specular))
            //if ((bxdf.Type & BxDFType.BSDF_SPECULAR) == 0)
            {
                var f = RgbSpectrum.ZeroSpectrum();
                if ((Vector.Dot(ref N,ref wi)) * Vector.Dot(ref N, ref wo) > 0f)
                // ignore BTDFs
                {
                    fl = fl & ~BxDFType.Transmission;
                }
                else
                    // ignore BRDFs
                    fl = (fl & ~BxDFType.Reflection);
                for (int i = 0; i < Bxdfs.Length; ++i)
                    if ((Bxdfs[i].Type.HasFlag(fl)))
                        f +=  new RgbSpectrum(Bxdfs[i].Eval(ref wo, ref wi, ref N));
                sample.Spectrum = (f/pdf).ToArray();
            }
        }
Example #4
0
 public Spectrum F(Vector woW, Vector wiW, BxDFType flags)
 {
     Vector wi = WorldToLocal (wiW), wo = WorldToLocal (woW);
     if ((wiW ^ ng) * (woW ^ ng) > 0)
         flags &= ~BxDFType.BSDF_TRANSMISSION;
     else
         flags &= ~BxDFType.BSDF_REFLECTION;
     Spectrum f = new Spectrum ();
     for (int i = 0; i < nBxDFs; ++i)
         if (bxdfs[i].MatchesFlags (flags))
             f += bxdfs[i].F (wo, wi);
     return f;
 }
Example #5
0
        public RgbSpectrum F(ref Vector wi, ref Vector wo, ref Normal n, BxDFType type) {
            var current = type;
            var result = new RgbSpectrum();

            if (((Vector.Dot(ref wi, ref n)*Vector.Dot(ref wo, ref n)) > 0))
            {
                current = type & ~BxDFType.Reflection;
            }
            else {
                current = type & ~BxDFType.Transmission;
            }

            for (int index = 0; index < Bxdfs.Length; index++) {
                if (Bxdfs[index].Type.HasFlag(current))
                    result += new RgbSpectrum(Bxdfs[index].Eval(ref wo, ref wi, ref n));
            }
            return result;
        }
Example #6
0
 public double Pdf(Vector woW, Vector wiW, BxDFType flags)
 {
     if (nBxDFs == 0)
         return 0.0;
     Vector wo = WorldToLocal (woW), wi = WorldToLocal (wiW);
     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);
         }
     }
     return matchingComps > 0 ? pdf / matchingComps : 0.0;
 }
Example #7
0
 public bool MatchesFlags(BxDFType flags)
 {
     return (this.Type & flags) == this.Type;
 }
Example #8
0
        public override Spectrum Sample_f(Vector3 <float> wo, out Vector3 <float> wi, Point2 <float> u, out float pdf, out BxDFType sampledType)
        {
            pdf         = 0;
            sampledType = 0;

            // Sample microfacet orientation and compute the incoming direction
            var wh = distribution.Sample_wh(wo, u);

            wi = Reflect(wo, wh);

            // If the reflected direction is in the opposite hemisphere, no light is reflected
            if (!MathUtils.SameHemisphere(wo, wi))
            {
                return(Spectrum.Zero);
            }

            // Transform the PDF (Pdf() gives the distribution around the half-angle vector
            // but the integral requires the distribution around the incoming direction)
            pdf = distribution.Pdf(wo, wh) / (4 * wo.Dot(wh));

            return(f(wo, wi));
        }
Example #9
0
 public bool Matches(BxDFType type)
 {
     return((Type & type) == Type);
 }
Example #10
0
 public bool MatchesFlags(BxDFType flags)
 {
     return((type & flags) == type);
 }
Example #11
0
 public Spectrum Rho(BxDFType flags)
 {
     return Rho (flags, 6);
 }
Example #12
0
 public virtual float Pdf(ref Vector wo, ref Vector wi, BxDFType bxDFType) {
     return MathLab.INVTWOPI;
 }
Example #13
0
 public abstract void Sample(ref Vector wo, ref Normal N, ref Normal shadeN, float u0, float u1, float u2,out  BsdfSample sample,BxDFType type = BxDFType.AllTypes);
Example #14
0
 public int NumComponents(BxDFType flags) {
     var res = Bxdfs.Count(p => MatchesFlags(p.Type, flags));
     return res;
 }
Example #15
0
 public static bool MatchesFlags(BxDFType obj, BxDFType flags)
 {
     return (flags & obj).Equals(flags) || (flags & obj).Equals(obj);
 }
Example #16
0
        public override Spectrum Sample_f(Vector3 <float> wo, out Vector3 <float> wi, Point2 <float> sample, out float pdf, out BxDFType type)
        {
            // Compute the perfect specular reflection direction
            //
            // In polar coordinates:
            //   phi_o = phi_i + pi
            //   theta_o = theta_i
            wi = new Vector3 <float>(-wo.X, -wo.Y, wo.Z); // Simplified because we are in the BRDF coordinate frame

            pdf    = 1;
            sample = null;
            type   = 0; // TODO?
            return(fresnel.Evaluate(CosTheta(wi)) * reflectance * (1.0f / AbsCosTheta(wi)));
        }
Example #17
0
 public BxDF(BxDFType T)
 {
     type = T;
 }
Example #18
0
 public Spectrum Rho(Vector wo, BxDFType flags)
 {
     return Rho (wo, flags, 6);
 }
Example #19
0
 public BxDF(BxDFType type)
 {
     Type = type;
 }
Example #20
0
 public Spectrum Rho(Vector wo, BxDFType flags, int sqrtSamples)
 {
     int nSamples = sqrtSamples * sqrtSamples;
     double[] s1 = new double[2 * nSamples];
     MonteCarlo.StratifiedSample2D (s1, sqrtSamples, sqrtSamples, true);
     Spectrum ret = new Spectrum ();
     for (int i = 0; i < nBxDFs; ++i)
         if (bxdfs[i].MatchesFlags (flags))
             ret += bxdfs[i].Rho (wo, nSamples, s1);
     return ret;
 }
Example #21
0
        // Sample an incoming direction for the given outgoing direction
        public virtual Spectrum Sample_f(Vector3 <float> wo, out Vector3 <float> wi, Point2 <float> sample, out float pdf, out BxDFType type)
        {
            // The default implementation samples the hemisphere with a cosine-weighted distribution
            wi = MathUtils.CosineSampleHemisphere(sample);

            // Flip the incoming direction to be in the same hemisphere as the outgoing direction
            if (wo.Z < 0)
            {
                wi.Z *= -1;
            }

            // Probability Density Function
            //  - if not on the same hemisphere: 0
            //  - otherwise: wi . n
            pdf = Pdf(wo, wi);

            type = 0;

            return(f(wo, wi));
        }
Example #22
0
 public Spectrum SampleF(Vector wo, ref Vector wi, BSDFSample bsdfSample, ref double pdf, BxDFType flags)
 {
     BxDFType temp = BxDFType.BSDF_ALL;
     return SampleF (wo, ref wi, bsdfSample, ref pdf, flags, ref temp);
 }
Example #23
0
 protected BxDF(BxDFType type)
 {
     Type = type;
 }
Example #24
0
        public Spectrum SampleF(Vector woW, ref Vector wiW, BSDFSample bsdfSample, ref double pdf, BxDFType flags, ref BxDFType sampledType)
        {
            int matchingComps = NumComponents (flags);
            if (matchingComps == 0)
            {
                pdf = 0.0;
                return new Spectrum ();
            }

            int which = Math.Min (Util.Floor2Int (bsdfSample.uComponent * matchingComps), matchingComps - 1);

            BxDF bxdf = null;
            int count = which;
            for (int i = 0; i < nBxDFs; ++i)
            {
                if (bxdfs[i].MatchesFlags (flags) && count-- == 0)
                {
                    bxdf = bxdfs[i];
                    break;
                }
            }

            Vector wo = WorldToLocal (woW);
            Vector wi = new Vector ();
            pdf = 0.0;
            Spectrum f = bxdf.SampleF (wo, ref wi, bsdfSample.uDir[0], bsdfSample.uDir[1], ref pdf);

            if (pdf == 0.0)
            {
                return new Spectrum ();
            }

            sampledType = bxdf.Type;
            wiW = LocalToWorld (wi);

            if ((bxdf.Type & BxDFType.BSDF_SPECULAR) == 0 && matchingComps > 1)
                for (int i = 0; i < nBxDFs; ++i)
                    if (bxdfs[i] != bxdf && bxdfs[i].MatchesFlags (flags))
                        pdf += bxdfs[i].Pdf (wo, wi);
            if (matchingComps > 1)
                pdf /= matchingComps;

            if ((bxdf.Type & BxDFType.BSDF_SPECULAR) == 0)
            {
                f = new Spectrum ();
                if ((wiW ^ ng) * (woW ^ ng) > 0.0)
                    flags &= ~BxDFType.BSDF_TRANSMISSION;
                else
                    flags &= ~BxDFType.BSDF_REFLECTION;

                for (int i = 0; i < nBxDFs; ++i)
                    if (bxdfs[i].MatchesFlags (flags))
                        f += bxdfs[i].F (wo, wi);
            }

            return f;
        }
Example #25
0
        public override Spectrum Sample_f(Vector3 <float> wo, out Vector3 <float> wi, Point2 <float> u, out float pdf, out BxDFType sampledType)
        {
            pdf         = 0;
            sampledType = 0;

            // Cosine-sample the hemisphere
            if (u.X < 0.5f)
            {
                u.X *= 2; // Remap the sample to avoid each path to have samples covering only half the range of possible value

                wi = MathUtils.CosineSampleHemisphere(u);

                if (wo.Z < 0)
                {
                    wi.Z = -wi.Z;
                }
            }
            // Sample the microfacet orientation
            else
            {
                u.X = 2 * (u.X - 0.5f); // Remap

                var wh = distribution.Sample_wh(wo, u);
                wi = Reflect(wo, wh);

                if (!MathUtils.SameHemisphere(wo, wi))
                {
                    return(Spectrum.Zero);
                }
            }

            pdf = Pdf(wo, wi);
            return(f(wo, wi));
        }
Example #26
0
 public BxDF(BxDFType type)
 {
     this.Type = type;
 }