예제 #1
0
        public static Spectrum SpecularTransmit(RayDifferential ray, Bsdf bsdf,
                                                Random rng, Intersection isect, Renderer renderer,
                                                Scene scene, Sample sample)
        {
            Vector   wo = -ray.Direction, wi;
            float    pdf;
            Point    p = bsdf.DgShading.Point;
            Normal   n = bsdf.DgShading.Normal;
            Spectrum f = bsdf.SampleF(wo, out wi, new BsdfSample(rng), out pdf,
                                      BxdfType.Transmission | BxdfType.Specular);
            Spectrum L = Spectrum.CreateBlack();

            if (pdf > 0.0f && !f.IsBlack && Vector.AbsDot(wi, n) != 0.0f)
            {
                // Compute ray differential _rd_ for specular transmission
                var rd = new RayDifferential(p, wi, ray, isect.RayEpsilon);
                if (ray.HasDifferentials)
                {
                    rd.HasDifferentials = true;
                    rd.RxOrigin         = p + isect.DifferentialGeometry.DpDx;
                    rd.RyOrigin         = p + isect.DifferentialGeometry.DpDy;

                    float  eta = bsdf.Eta;
                    Vector w   = -wo;
                    if (Vector.Dot(wo, n) < 0)
                    {
                        eta = 1.0f / eta;
                    }

                    Normal dndx = bsdf.DgShading.DnDu * bsdf.DgShading.DuDx +
                                  bsdf.DgShading.DnDv * bsdf.DgShading.DvDx;
                    Normal dndy = bsdf.DgShading.DnDu * bsdf.DgShading.DuDy +
                                  bsdf.DgShading.DnDv * bsdf.DgShading.DvDy;

                    Vector dwodx = -ray.RxDirection - wo, dwody = -ray.RyDirection - wo;
                    float  dDNdx = Vector.Dot(dwodx, n) + Vector.Dot(wo, dndx);
                    float  dDNdy = Vector.Dot(dwody, n) + Vector.Dot(wo, dndy);

                    float mu    = eta * Vector.Dot(w, n) - Vector.Dot(wi, n);
                    float dmudx = (eta - (eta * eta * Vector.Dot(w, n)) / Vector.Dot(wi, n)) * dDNdx;
                    float dmudy = (eta - (eta * eta * Vector.Dot(w, n)) / Vector.Dot(wi, n)) * dDNdy;

                    rd.RxDirection = wi + eta * dwodx - (Vector)(mu * dndx + dmudx * n);
                    rd.RyDirection = wi + eta * dwody - (Vector)(mu * dndy + dmudy * n);
                }
                Spectrum Li = renderer.Li(scene, rd, sample, rng);
                L = f * Li * Vector.AbsDot(wi, n) / pdf;
            }
            return(L);
        }
예제 #2
0
파일: Bxdf.cs 프로젝트: MassVOiD/aether
        public virtual Spectrum Rho(Vector wo, int numSamples, float[] samples)
        {
            Spectrum r = Spectrum.CreateBlack();

            for (int i = 0; i < numSamples; ++i)
            {
                // Estimate one term of $\rho_\roman{hd}$
                Vector   wi;
                float    pdf;
                Spectrum f = SampleF(wo, out wi, samples[2 * i], samples[2 * i + 1], out pdf);
                if (pdf > 0.0f)
                {
                    r += f * ReflectionUtilities.AbsCosTheta(ref wi) / pdf;
                }
            }
            return(r / numSamples);
        }
예제 #3
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);
        }
예제 #4
0
        public override Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray, Intersection intersection,
                                    Sample sample, Random rng)
        {
            Spectrum L = Spectrum.CreateBlack();
            // Compute emitted and reflected light at ray intersection point

            // Evaluate BSDF at hit point
            var bsdf = intersection.GetBsdf(ray);

            // Initialize common variables for Whitted integrator
            Point  p  = bsdf.DgShading.Point;
            Normal n  = bsdf.DgShading.Normal;
            Vector wo = -ray.Direction;

            // Compute emitted light if ray hit an area light source
            L += intersection.Le(wo);

            // Add contribution of each light source
            foreach (var light in scene.Lights)
            {
                Vector           wi;
                float            pdf;
                VisibilityTester visibility;
                Spectrum         Li = light.SampleL(p, intersection.RayEpsilon,
                                                    new LightSample(rng), ray.Time, out wi, out pdf, out visibility);
                if (Li.IsBlack || pdf == 0.0f)
                {
                    continue;
                }
                Spectrum f = bsdf.F(wo, wi);
                if (!f.IsBlack && visibility.Unoccluded(scene))
                {
                    L += f * Li * Vector.AbsDot(wi, n)
                         * visibility.Transmittance(scene, renderer, sample, rng)
                         / pdf;
                }
            }
            if (ray.Depth + 1 < _maxDepth)
            {
                // Trace rays for specular reflection and refraction
                L += IntegratorUtilities.SpecularReflect(ray, bsdf, rng, intersection, renderer, scene, sample);
                L += IntegratorUtilities.SpecularTransmit(ray, bsdf, rng, intersection, renderer, scene, sample);
            }
            return(L);
        }
예제 #5
0
파일: Bxdf.cs 프로젝트: MassVOiD/aether
        public virtual Spectrum Rho(int numSamples, float[] samples1, float[] samples2)
        {
            Spectrum r = Spectrum.CreateBlack();

            for (int i = 0; i < numSamples; ++i)
            {
                // Estimate one term of $\rho_\roman{hh}$
                Vector wo, wi;
                wo = MonteCarloUtilities.UniformSampleHemisphere(samples1[2 * i], samples1[2 * i + 1]);
                float    pdf_o = MathUtility.InvTwoPi, pdf_i;
                Spectrum f = SampleF(wo, out wi, samples2[2 * i], samples2[2 * i + 1], out pdf_i);
                if (pdf_i > 0.0f)
                {
                    r += f * ReflectionUtilities.AbsCosTheta(ref wi) * ReflectionUtilities.AbsCosTheta(ref wo) / (pdf_o * pdf_i);
                }
            }
            return(r / (MathUtility.Pi * numSamples));
        }
예제 #6
0
        public override Spectrum Li(Scene scene, RayDifferential ray, Sample sample, Random rng, ref Intersection intersection, out Spectrum t)
        {
            Debug.Assert(ray.Time == sample.Time);
            Spectrum Li = Spectrum.CreateBlack();

            if (scene.TryIntersect(ray, ref intersection))
            {
                Li = _surfaceIntegrator.Li(scene, this, ray, intersection, sample, rng);
            }
            else
            {
                // Handle ray that doesn't intersect any geometry
                foreach (var light in scene.Lights)
                {
                    Li += light.Le(ray);
                }
            }
            Spectrum Lvi = _volumeIntegrator.Li(scene, this, ray, sample, rng, out t);

            return(t * Li + Lvi);
        }
예제 #7
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);
        }
예제 #8
0
 public override Spectrum Li(Scene scene, Renderer renderer, RayDifferential ray, Sample sample, Random rng, out Spectrum transmittance)
 {
     // TODO
     transmittance = new Spectrum(1.0f);
     return(Spectrum.CreateBlack());
 }
예제 #9
0
 public virtual Spectrum Le(RayDifferential r)
 {
     return(Spectrum.CreateBlack());
 }
예제 #10
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);
        }