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); }
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); }
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); }