예제 #1
0
        public override bool Intersect(Ray ray, out Surfel surfel)
        {
            var dot = Vector3.Dot(normal, ray.direction);

            if (dot > e)
            {
                var dir = point - ray.origin;
                var t   = Vector3.Dot(dir, normal) / dot;
                if (t > 0)
                {
                    var p    = ray.GetPoint(t);
                    var dist = Vector3.DistanceSquared(p, point);
                    if (dist <= radius * radius)
                    {
                        surfel = new Surfel()
                        {
                            t      = t,
                            point  = p,
                            normal = -normal
                        };
                        return(true);
                    }
                }
            }
            surfel = null;
            return(false);
        }
예제 #2
0
        public override float Sample(Surfel surfel, out Vector3 wi, Vector2 sample, out float pdf)
        {
            var wo       = surfel.ray;
            var entering = Vector3.Dot(wo, surfel.normal) < 0;
            var etaI     = entering ? etaA : etaB;
            var etaT     = entering ? etaB : etaA;
            var eta      = etaI / etaT;
            var n        = Vector3Extensions.Faceforward(surfel.normal, wo);

            if (!wo.Refract(n, eta, out wi))
            {
                pdf = 0;
                return(0);
            }

            pdf = 1;
            var cos = Vector3.Dot(wi, surfel.normal);
            var ft  = t * (1 - fresnel.Evaluate(cos));

            if (mode == TransportMode.Radiance)
            {
                ft *= (etaI * etaI) / (etaT * etaT);
            }
            return(ft / Math.Abs(cos));
        }
예제 #3
0
        public override float Sample(Surfel surfel, out Vector3 wi, Vector2 sample, out float pdf)
        {
            pdf = 1;
            var wo = surfel.ray;

            wi = wo.Reflect(surfel.normal);
            var cos = Vector3.Dot(wi, surfel.normal);

            return(fresnel.Evaluate(cos) * r / Math.Abs(cos));
        }
예제 #4
0
        public override bool Intersect(Ray ray, out Surfel surfel)
        {
            var f1     = ray.origin.X - center.X;
            var f2     = ray.origin.Y - center.Y;
            var f3     = ray.origin.Z - center.Z;
            var aCoeff = ray.direction.X * ray.direction.X +
                         ray.direction.Y * ray.direction.Y +
                         ray.direction.Z * ray.direction.Z;
            var halfBCoeff = ray.direction.X * f1 + ray.direction.Y * f2 + ray.direction.Z * f3;
            var cCoeff     = f1 * f1 + f2 * f2 + f3 * f3 - radius * radius;

            var discriminant = halfBCoeff * halfBCoeff - aCoeff * cCoeff;

            if (discriminant < 0)
            {
                surfel = null;
                return(false);
            }

            float t;

            if (discriminant == 0)
            {
                t = (float)Math.Sqrt(aCoeff * cCoeff);
            }
            else
            {
                var sqrDiscriminant = Math.Sqrt(discriminant);
                var k1 = (-halfBCoeff + sqrDiscriminant) / aCoeff;
                var k2 = (-halfBCoeff - sqrDiscriminant) / aCoeff;

                k1 = k1 > 0 ? k1 : k2;
                k2 = k2 > 0 ? k2 : k1;
                if (k2 < 0)
                {
                    surfel = null;
                    return(false);
                }

                t = (float)Math.Min(k1, k2);
            }

            var p = ray.GetPoint(t);

            surfel = new Surfel()
            {
                point  = p,
                normal = (p - center).Normalize(),
                t      = t
            };
            return(true);
        }
예제 #5
0
        public override float Sample(Surfel surfel, out Vector3 wi, Vector2 sample, out float pdf)
        {
            var wo = surfel.ray;
            var up = surfel.normal;

            wi = Mathf.CosineSampleHemisphere(up, sample);
            if (Vector3.Dot(wo, up) < 0)
            {
                wi.Z *= -1;
            }
            pdf = sample.X;
            return(Evaluate(wo, wi));
        }
예제 #6
0
 public bool Intersect(Ray ray, out Surfel surfel)
 {
     if (children.Count == 0 && objects.Count == 0)
     {
         surfel = null;
         return(false);
     }
     if (!box.Intersect(ray, out surfel))
     {
         surfel = null;
         return(false);
     }
     return(children.Count > 0 ? IntersectChildren(ray, out surfel) : IntersectObjects(ray, out surfel));
 }
예제 #7
0
 public bool Intersect(Ray ray, out Surfel surfel)
 {
     if (children.Count == 0 && mesh.triangles.Count == 0)
     {
         surfel = null;
         return(false);
     }
     if (!mesh.BoundingBox.Intersect(ray, out surfel))
     {
         surfel = null;
         return(false);
     }
     return(children.Count > 0 ? IntersectChildren(ray, out surfel) : mesh.Intersect(ray, out surfel));
 }
예제 #8
0
        public override bool Intersect(Ray ray, out Surfel surfel)
        {
            var edge1 = v1 - v0;
            var edge2 = v2 - v0;

            var h = Vector3.Cross(ray.direction, edge2);
            var a = Vector3.Dot(edge1, h);

            if (Math.Abs(a) < e)
            {
                surfel = null;
                return(false);
            }

            var f = 1f / a;
            var s = ray.origin - v0;
            var u = f * Vector3.Dot(s, h);

            if (u < 0 || u > 1)
            {
                surfel = null;
                return(false);
            }

            var q = Vector3.Cross(s, edge1);
            var v = f * Vector3.Dot(ray.direction, q);

            if (v < 0 || u + v > 1)
            {
                surfel = null;
                return(false);
            }

            var t = f * Vector3.Dot(edge2, q);

            if (t <= 0)
            {
                surfel = null;
                return(false);
            }

            surfel = new Surfel()
            {
                point  = ray.GetPoint(t),
                normal = n0 * (1 - u - v) + n1 * u + n2 * v,
                t      = t
            };
            return(true);
        }
예제 #9
0
        public override float Sample(Surfel surfel, out Vector3 wi, Vector2 sample, out float pdf)
        {
            float res;
            var   f = fresnel.Evaluate(Vector3.Dot(surfel.normal, surfel.ray));

            if (sample.X < f)
            {
                res = reflection.Sample(surfel, out wi, sample, out pdf);
                pdf = f;
            }
            else
            {
                res = transmission.Sample(surfel, out wi, sample, out pdf);
                pdf = 1 - f;
            }
            return(res);
        }
예제 #10
0
        private bool IntersectChildren(Ray ray, out Surfel surfel)
        {
            surfel = null;
            var intersected = false;

            foreach (var node in children)
            {
                if (node.Intersect(ray, out var s))
                {
                    if (surfel == null || surfel.t > s.t)
                    {
                        surfel      = s;
                        intersected = true;
                    }
                }
            }
            return(intersected);
        }
예제 #11
0
        public override bool Intersect(Ray ray, out Surfel surfel)
        {
            surfel = null;
            var intersected = false;

            foreach (var t in triangles)
            {
                if (t.Intersect(ray, out var s))
                {
                    if (surfel == null || surfel.t > s.t)
                    {
                        surfel      = s;
                        intersected = true;
                    }
                }
            }
            return(intersected);
        }
예제 #12
0
        private bool IntersectObjects(Ray ray, out Surfel surfel)
        {
            surfel = null;
            var intersected = false;

            foreach (var obj in objects)
            {
                if (obj.mesh.Intersect(ray, out var s))
                {
                    intersected = true;
                    if (surfel == null || surfel.t > s.t)
                    {
                        surfel          = s;
                        surfel.material = obj.material;
                        surfel.ray      = ray.direction;
                    }
                }
            }
            return(intersected);
        }
예제 #13
0
 public override float Sample(Surfel surfel, out Vector3 wi, out float pdf)
 {
     return(brdf.Sample(surfel, out wi, Mathf.CreateSample(), out pdf));
 }
예제 #14
0
        public override bool Intersect(Ray ray, out Surfel surfel)
        {
            var invdir = new Vector3(1 / ray.direction.X, 1 / ray.direction.Y, 1 / ray.direction.Z);

            var xmin = invdir.X >= 0 ? min.X : max.X;
            var xmax = invdir.X >= 0 ? max.X : min.X;
            var tmin = (xmin - ray.origin.X) * invdir.X;
            var tmax = (xmax - ray.origin.X) * invdir.X;

            var ymin  = invdir.Y >= 0 ? min.Y : max.Y;
            var ymax  = invdir.Y >= 0 ? max.Y : min.Y;
            var tymin = (ymin - ray.origin.Y) * invdir.Y;
            var tymax = (ymax - ray.origin.Y) * invdir.Y;

            if (tmin > tymax || tymin > tmax)
            {
                surfel = null;
                return(false);
            }
            tmin = Math.Max(tmin, tymin);
            tmax = Math.Min(tmax, tymax);

            var zmin  = invdir.Z >= 0 ? min.Z : max.Z;
            var zmax  = invdir.Z >= 0 ? max.Z : min.Z;
            var tzmin = (zmin - ray.origin.Z) * invdir.Z;
            var tzmax = (zmax - ray.origin.Z) * invdir.Z;

            if (tmin > tzmax || tzmin > tmax)
            {
                surfel = null;
                return(false);
            }
            tmin = Math.Max(tmin, tzmin);
            tmax = Math.Min(tmax, tzmax);

            float t;

            if (tmin < 0)
            {
                if (tmax < 0)
                {
                    surfel = null;
                    return(false);
                }
                t = tmax;
            }
            else
            {
                t = Math.Min(tmin, tmax);
            }

            var p = ray.GetPoint(t);

            surfel = new Surfel()
            {
                t      = t,
                point  = p,
                normal = GetNormal(p),
            };
            return(true);
        }
예제 #15
0
 public abstract bool Intersect(Ray ray, out Surfel surfel);
예제 #16
0
 public abstract float Sample(Surfel surfel, out Vector3 wi, Vector2 sample, out float pdf);
예제 #17
0
 public override bool Intersect(Ray ray, out Surfel surfel)
 {
     return(tree.Intersect(ray, out surfel));
 }
예제 #18
0
 public bool Intersect(Ray ray, out Surfel surfel)
 {
     return(root.Intersect(ray, out surfel));
 }