示例#1
0
        private Vector TraceRay(Vector O, Vector D, double tMin, double tMax, int depth)
        {
            var(closestPrimitive, closest_t) = ClosestIntersection(O, D, tMin, tMax);
            if (closestPrimitive == null)
            {
                return(Vector.FromColor(_options.BgColor));
            }

            var view = D.Multiply(-1);
            var P    = O.Add(D.Multiply(closest_t));

            Vector normal = new Vector();

            if (closestPrimitive is Plane plane)
            {
                normal = plane.Normal;
            }

            if (closestPrimitive is Sphere sphere)
            {
                if (sphere.LightTransparent)
                {
                    return(Vector.FromColor(sphere.Color));
                }
                normal = P.Subtract(sphere.Center);
            }

            if (closestPrimitive is Box box)
            {
                normal = box.GetNormal(O, D, tMin);
            }
            if (closestPrimitive is Surface surface)
            {
                normal = surface.GetNormal(O, D, closest_t);
            }
            if (closestPrimitive is Torus torus)
            {
                normal = torus.GetNormal(O, D, closest_t);
            }

            if (closestPrimitive is Disk disk)
            {
                normal = disk.GetNormal();
            }

            normal = normal.Multiply(1 / normal.Lenght()); //unit vector
            if (normal.DotProduct(D) > 0)
            {
                normal = normal.Multiply(-1);
            }

            var color = closestPrimitive.Color;

            if (closestPrimitive is Plane)
            {
                var x = (int)Math.Round(O.D1 + D.D1 * closest_t) % 2;
                var z = (int)Math.Round(O.D3 + D.D3 * closest_t) % 2;
                if (x == z)
                {
                    color = Color.FromRgb(0, 0, 0);
                }
            }

            var local_color = Vector.FromColor(color)
                              .Multiply(ComputeLighting(P, normal, view, closestPrimitive.Specular));

            var r = closestPrimitive.Reflect;

            if (depth <= 0 || r <= 0)
            {
                return(local_color);
            }

            var R = ReflectRay(view, normal);
            var reflectedColor = TraceRay(P, R, 0.001d, double.PositiveInfinity, depth - 1);

            return(local_color.Multiply(1 - r).Add(reflectedColor.Multiply(r)));
        }
示例#2
0
 private Vector ReflectRay(Vector r, Vector normal)
 {
     return(normal.Multiply(2 * r.DotProduct(normal)).Subtract(r));
 }