Example #1
0
        public static bool Contains3DPoint(Vector3 point, bool checkOnPlane, Vector3 quadCenter, float quadWidth, float quadHeight, Vector3 quadRight,
                                           Vector3 quadUp, QuadEpsilon epsilon = new QuadEpsilon())
        {
            Plane quadPlane = new Plane(Vector3.Cross(quadRight, quadUp).normalized, quadCenter);

            if (checkOnPlane && quadPlane.GetAbsDistanceToPoint(point) > epsilon.ExtrudeEps)
            {
                return(false);
            }

            quadWidth  += epsilon.WidthEps;
            quadHeight += epsilon.HeightEps;

            Vector3 toPoint  = point - quadCenter;
            float   dotRight = toPoint.AbsDot(quadRight);
            float   dotUp    = toPoint.AbsDot(quadUp);

            if (dotRight > quadWidth * 0.5f)
            {
                return(false);
            }
            if (dotUp > quadHeight * 0.5f)
            {
                return(false);
            }

            return(true);
        }
        public override Vector3 Sample_F(ShadeRec sr, Vector3 wo, ref Vector3 wr)
        {
            float ndotwo = Vector3.Dot(sr.Normal, wo);

            wr = -wo + 2.0f * sr.Normal * ndotwo;
            return(fresnel(sr) * Colors.White / Vector3.AbsDot(sr.Normal, wr));
        }
        public override Vector3 Sample_F(ShadeRec sr, Vector3 wo, ref Vector3 wi)
        {
            float ndotwo = Vector3.Dot(sr.Normal, wo);

            wi = -wo + 2.0f * sr.Normal * ndotwo;
            return(kr * cr.GetColor(sr) / Vector3.AbsDot(sr.Normal, wi));
        }
Example #4
0
 //
 public float Pdf(Vector3 <float> wo, Vector3 <float> wh)
 {
     if (sampleVisibleArea)
     {
         return(D(wh) * G1(wo) * Vector3 <float> .AbsDot(wo, wh) / BxDF.AbsCosTheta(wo));
     }
     else
     {
         return(D(wh) * BxDF.AbsCosTheta(wo));
     }
 }
Example #5
0
        public virtual float Pdf(Interaction inter, Vector3 <float> wi)
        {
            var ray = inter.SpawnRay(wi);

            if (!Intersect(ray, out float tHit, out SurfaceInteraction intersection))
            {
                return(0);
            }

            return((inter.P - intersection.P).LengthSquared() /
                   (Vector3 <float> .AbsDot(-wi, intersection.N) * Area()));
        }
Example #6
0
 public static bool IsAligned(this Vector3 vector, Vector3 other, bool checkSameDirection)
 {
     if (!checkSameDirection)
     {
         float absDot = vector.AbsDot(other);
         return(Mathf.Abs(absDot - 1.0f) < 1e-5f);
     }
     else
     {
         float dot = vector.Dot(other);
         return(dot > 0.0f && Mathf.Abs(dot - 1.0f) < 1e-5f);
     }
 }
Example #7
0
        public static int GetMostAligned(Vector3[] vectors, Vector3 dir, bool checkSameDirection)
        {
            if (vectors.Length == 0)
            {
                return(-1);
            }

            float bestAlignment = float.MinValue;
            int   bestIndex     = -1;

            if (!checkSameDirection)
            {
                // Loop through each test vector
                for (int dirIndex = 0; dirIndex < vectors.Length; ++dirIndex)
                {
                    // Calculate the absolute dot product with 'dir'. If this is gerater
                    // than what we have so far, it means we found vector which is more
                    // aligned with 'dir'.
                    Vector3 testDir = vectors[dirIndex];
                    float   absDot  = testDir.AbsDot(dir);
                    if (absDot > bestAlignment)
                    {
                        bestAlignment = absDot;
                        bestIndex     = dirIndex;
                    }
                }

                return(bestIndex);
            }
            else
            {
                // Loop through each test vector
                for (int dirIndex = 0; dirIndex < vectors.Length; ++dirIndex)
                {
                    // Calculate the dot product with 'dir'. If this is gerater than 0
                    // and greater than what we have so far, it means we found vector
                    // which is more aligned with 'dir'.
                    Vector3 testDir = vectors[dirIndex];
                    float   dot     = testDir.Dot(dir);
                    if (dot > 0.0f && dot > bestAlignment)
                    {
                        bestAlignment = dot;
                        bestIndex     = dirIndex;
                    }
                }

                return(bestIndex);
            }
        }
Example #8
0
        public override Vector3 Sample_F(ShadeRec sr, Vector3 wo, ref Vector3 wt)
        {
            Vector3 n          = (sr.Normal);
            float   cos_thetai = Vector3.Dot(n, wo);

            float eta = eta_in / eta_out;

            if (cos_thetai < 0.0)
            {
                cos_thetai = -cos_thetai;
                n          = -n;
                eta        = 1.0f / eta;
            }

            float temp       = 1.0f - (1.0f - cos_thetai * cos_thetai) / (eta * eta);
            float cos_theta2 = MathUtil.Sqrt(temp);

            wt = -wo / eta - (cos_theta2 - cos_thetai / eta) * n;
            return(fresnel(sr) / (eta * eta) * Colors.White / Vector3.AbsDot(sr.Normal, wt));
        }
        private Spectrum SpecularReflect(RayDifferential ray, SurfaceInteraction inter, Scene scene, Camera camera, Sampler sampler, int depth)
        {
            // Sample a direction with the BSDF
            var type = BxDFType.Reflection | BxDFType.Specular;
            var f    = inter.Bsdf.Sample_f(inter.Wo, out Vector3 <float> wi, sampler.Get2D(), out float pdf, type, out BxDF.BxDFType sampledType);

            // Add the contribution of this reflection
            if (pdf > 0 && !f.IsBlack() && Vector3 <float> .AbsDot(wi, inter.Shading.N) != 0)
            {
                var newRay = inter.SpawnRay(wi).ToDiff();

                if (ray.HasDifferentials)
                {
                    // TODO
                }

                return(f * Li(newRay, scene, camera, sampler, depth + 1) * Vector3 <float> .AbsDot(wi, inter.Shading.N) * (1.0f / pdf));
            }

            return(Spectrum.Zero);
        }
        public override Vector3 Shade(ShadeRec sr)
        {
            Vector3 L             = base.Shade(sr);
            Vector3 wo            = -sr.Ray.Direction;
            Vector3 wi            = Vector3.Zero();
            Vector3 fr            = reflective.Sample_F(sr, wo, ref wi);
            Ray     reflected_ray = new Ray(sr.HitPoint, wi);

            if (specular_btdf.TIR(sr))
            {
                L += sr.World.Tracer.TraceRay(reflected_ray, sr.Depth + 1);
            }
            else
            {
                Vector3 wt = Vector3.Zero();
                Vector3 ft = specular_btdf.Sample_F(sr, wo, ref wt);
                Ray     transmitted_ray = new Ray(sr.HitPoint, wt);
                L += fr * sr.World.Tracer.TraceRay(reflected_ray, sr.Depth + 1) * Vector3.AbsDot(sr.Normal, wi);
                L += ft * sr.World.Tracer.TraceRay(transmitted_ray, sr.Depth + 1) * Vector3.AbsDot(sr.Normal, wt);              //this is very important for transparent rendering
            }
            return(L);
        }
Example #11
0
        public static Spectrum EstimateDirect(Interaction inter, Point2 <float> scattering, Light light, Point2 <float> lightPoint, Scene scene, Sampler sampler, bool specular = false)
        {
            var bsdfType = specular ? BxDFType.All : BxDFType.All & ~BxDFType.Specular;

            var   Ld = Spectrum.Zero;
            float scatteringPdf, lightPdf;

            // Sampling the BSDF works well with highly specular materials and large light sources.
            // Sampling the light source works well with small sources and rough materials.
            //
            // To handle most cases, we do both:
            //   1. Sample the light source (gives a radiance, a PDF, an incoming direction)
            //        -> evaluate the BSDF for those parameters
            //   2. Sample the BSDF
            //        -> compute the radiance along the incoming direction

            // 1. Sample the light source

            var Li = light.Sample_Li(inter, lightPoint, out Vector3 <float> wi, out lightPdf, out VisibilityTester visibility);

            if (lightPdf > 0 && !Li.IsBlack())
            {
                // Evaluate the BSDF value for the light sample
                Spectrum f;
                if (inter.IsSurfaceInteraction())
                {
                    var sinter = (SurfaceInteraction)inter;
                    f = sinter.Bsdf.f(sinter.Wo, wi, bsdfType) * Vector3 <float> .AbsDot(wi, sinter.Shading.N);

                    scatteringPdf = sinter.Bsdf.Pdf(sinter.Wo, wi, bsdfType);
                }
                else
                {
                    // Medium interaction
                    throw new NotImplementedException();
                }

                if (!f.IsBlack() && visibility.Unoccluded(scene))
                {
                    // Delta lights: do not apply multiple importance sampling
                    if (light.IsDeltaLight())
                    {
                        Ld += f * Li / lightPdf;
                    }
                    else
                    {
                        var weight = MathUtils.PowerHeuristic(1, lightPdf, 1, scatteringPdf);
                        Ld += f * Li * weight / lightPdf;
                    }
                }
            }

            // 2. Sample the BSDF

            if (!light.IsDeltaLight())
            {
                var sampledSpecular = false;

                // Sample scattered direction
                Spectrum f;
                if (inter.IsSurfaceInteraction())
                {
                    var sinter = (SurfaceInteraction)inter;
                    f  = sinter.Bsdf.Sample_f(sinter.Wo, out wi, scattering, out scatteringPdf, bsdfType, out BxDFType sampledType);
                    f *= Vector3 <float> .AbsDot(wi, sinter.Shading.N);

                    sampledSpecular = (sampledType & BxDFType.Specular) > 0;
                }
                else
                {
                    // Medium interaction
                    throw new NotImplementedException();
                }

                if (!f.IsBlack() && scatteringPdf > 0)
                {
                    var weight = 1f;
                    if (!sampledSpecular)
                    {
                        lightPdf = light.Pdf_Li(inter, wi);
                        if (lightPdf == 0)
                        {
                            return(Ld);
                        }

                        weight = MathUtils.PowerHeuristic(1, scatteringPdf, 1, lightPdf);
                    }

                    // Transmittance would be done here
                    var Tr = Spectrum.One;

                    var ray = inter.SpawnRay(wi);
                    var foundSurfaceInteraction = scene.Intersect(ray, out SurfaceInteraction lightInter);

                    // Add light contribution
                    Li = Spectrum.Zero;
                    if (foundSurfaceInteraction)
                    {
                        if (lightInter.Primitive.GetAreaLight() == light)
                        {
                            Li = lightInter.Le(-wi);
                        }
                    }
                    else
                    {
                        //Li = light.Le(ray);
                    }

                    if (!Li.IsBlack())
                    {
                        Ld += f * Li * Tr * weight / scatteringPdf;
                    }
                }
            }

            return(Ld);
        }
Example #12
0
        public override Spectrum Li(RayDifferential ray, Scene scene, Camera camera, Sampler sampler, int depth = 0)
        {
            var L = Spectrum.Zero;

            // If the ray doesn't intersect the scene, return the background radiance
            if (!scene.Intersect(ray, out SurfaceInteraction inter) || inter == null)
            {
                foreach (var light in scene.Lights)
                {
                    L += light.Le(ray);
                }
                return(L);
            }

            // If the ray intersects something, we need to compute how the light is scattered

            var n  = inter.Shading.N;
            var wo = inter.Wo;

            inter.ComputeScatteringFunctions(ray);

            // Add the emissive contribution of the intersected object
            L += inter.Le(wo);

            // Add the direct contribution of each light source
            foreach (var light in scene.Lights)
            {
                // Sample the light source
                var Li = light.Sample_Li(inter, sampler.Get2D(), out Vector3 <float> wi, out float pdf, out VisibilityTester visibility);

                if (Li.IsBlack() || pdf == 0)
                {
                    continue;
                }

                // Evaluate the scattering at the interaction point
                var f = inter.Bsdf.f(wo, wi);

                // Trace a shadow ray to check that the point receives light
                if (!f.IsBlack())
                {
                    if (visibility.Unoccluded(scene))
                    {
                        L += f * Li * Vector3 <float> .AbsDot(wi, n.ToVector3()) * (1.0f / pdf);
                    }

                    /*else
                     *  L = new Spectrum(0, 0, 50);*/
                }
                else
                {
                }
            }

            // Recursively trace new rays
            if (depth + 1 < maxDepth)
            {
                L += SpecularReflect(ray, inter, scene, camera, sampler, depth);
                //L += SpecularTransmit(ray, inter, scene, sampler, depth);
            }

            return(L);
        }