Пример #1
0
        public RayTriangleIntersection IntersectionTest(Triangle triangle)
        {
            var result = new RayTriangleIntersection();

            result.triangle = triangle;
            result.ray      = this;

            var vx = triangle.RightCorner - this.origin;
            var vy = triangle.LeftCorner - this.origin;
            var vz = triangle.RootCorner - this.origin;

            Matrix3 mat = Matrix3.FromColumnVectors(vx, vy, vz);

            if (mat.Det == 0)//ray begin from triangle plane: no intersection
            {
                return(result);
            }
            Matrix3 matinv    = mat.Inv;
            Vector3 directive = matinv * direction;

            //if(directive.MagnitudeSqr == 0)  // impossible case

            if (directive.X < 0 || directive.Y < 0 || directive.Z < 0)
            {
                return(result);
            }


            directive         *= (1 / (directive.X + directive.Y + directive.Z));
            result.HitPoint    = mat * directive + this.origin;
            result.distance    = (result.HitPoint - this.origin).Magnitude;
            result.IsIntersect = true;
            return(result);
        }
Пример #2
0
        public RayTriangleIntersection IntersectionTest(Ray ray, List <Triangle> triangles)
        {
            RayTriangleIntersection firstIntersection = null;

            foreach (var tri in triangles)
            {
                var intersection = ray.IntersectionTest(tri);
                if (intersection.IsIntersect && intersection.distance > 0.000001)
                {
                    if (firstIntersection == null || firstIntersection.distance > intersection.distance)
                    {
                        firstIntersection = intersection;
                    }
                }
            }
            return(firstIntersection);
        }
Пример #3
0
        public Vector3 Trace(Ray ray, List <Triangle> triangles, int depth)
        {
            RayTriangleIntersection firstIntersection = IntersectionTest(ray, triangles);
            Material mat = defaultMat;

            //foreach (var tri in triangles)
            //{
            //    var intersection = ray.IntersectionTest(tri);
            //    if (intersection.IsIntersect && intersection.distance > 0.000001)
            //    {
            //        if (firstIntersection == null || firstIntersection.distance > intersection.distance)
            //        {
            //            firstIntersection = intersection;
            //        }
            //    }
            //}

            if (firstIntersection != null)
            {
                if (firstIntersection.triangle.material != null)
                {
                    mat = firstIntersection.triangle.material;
                }
            }
            else
            {
                return(new ZeroVector3());
            }

            if (depth <= 0)
            {
                return(mat.Ambient(firstIntersection.triangle.PlaneNormal, -ray.direction));
            }

            Vector3 sum = Vector3.Zero;
            //var randomDirections = RandomDirections.Get();
            //int cnt = (int)Math.Pow(16, depth);
            List <Vector3> dist    = SphericalCode.DepthDestMap[depth];
            var            randMat = Matrix3.RandomRotate();

            for (int ri = 0; ri < dist.Count; ri++)
            {
                //var dir = new Vector3(random.NextDouble() - 0.5, random.NextDouble() - 0.5, random.NextDouble() - 0.5);
                //dir *= 0.2;
                //dir += dist[ri];

                var dir = randMat * dist[ri];
                dir.Normalize();
                var commingLight = Trace(new Ray(firstIntersection.HitPoint, dir), triangles, depth - 1);
                foreach (var f in mat.lightDistributions)
                {
                    var factor        = f.GetFactor(firstIntersection.HitPoint, firstIntersection.triangle.PlaneNormal, -dir, -ray.direction);
                    var additionLight = new Vector3();
                    additionLight.X = commingLight.X * factor.X;
                    additionLight.Y = commingLight.Y * factor.Y;
                    additionLight.Z = commingLight.Z * factor.Z;
                    sum            += additionLight;
                }
            }
            sum *= 1.0 / dist.Count;
            Vector3 result = sum + mat.Ambient(firstIntersection.triangle.PlaneNormal, -ray.direction);

            return(result);
        }