示例#1
0
 /// <summary>
 /// Render the scene
 /// </summary>
 /// <param name="scene">The scene to render</param>
 public void Render(Scene scene)
 {
     for (int y = 0; y < scene.Camera.Screen.Height; y++)
     {
         for (int x = 0; x < scene.Camera.Screen.Width; x++)
         {
             var color = this.TraceRay(new Ray() { Start = scene.Camera.Position, Direction = scene.Camera.GetRayDirection(x, y) }, scene, 0);
             this.withResult(x, y, color.ToDrawingColor());
         }
     }
 }
示例#2
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="element"></param>
        /// <param name="position"></param>
        /// <param name="norm"></param>
        /// <param name="rayDirection"></param>
        /// <param name="scene"></param>
        /// <returns></returns>
        private Color GetNaturalColor(SceneObject element, Vector position, Vector norm, Vector rayDirection, Scene scene)
        {
            var ret = new Color(0, 0, 0);
            foreach (Light light in scene.Lights)
            {
                Vector lightDirection = light.Position - position;
                Vector lightUnitVector = lightDirection.Normalise;
                double intersectionDistance = scene.TestRay(new Ray() { Start = position, Direction = lightUnitVector });
                bool isInShadow = !((intersectionDistance > lightDirection.Magnitude) || (intersectionDistance == 0));

                if (!isInShadow)
                {
                    double angleOfIllumination = Vector.Dot(lightUnitVector, norm);
                    Color lcolor = angleOfIllumination > 0 ? angleOfIllumination * light.Color : new Color(0, 0, 0);
                    double specular = Vector.Dot(lightUnitVector, rayDirection.Normalise);
                    Color scolor = specular > 0 ? Color.Times(Math.Pow(specular, element.Surface.Roughness), light.Color) : new Color(0, 0, 0);
                    ret = ret + (element.Surface.Diffuse(position) * lcolor) + (element.Surface.Specular(position) * scolor);
                }
            }

            return ret;
        }
示例#3
0
        /// <summary>
        /// Get the color for the pixel
        /// </summary>
        /// <param name="intersection">The last point of intersection</param>
        /// <param name="scene">The scene description</param>
        /// <param name="depth">The current depth of recursion</param>
        /// <returns>The color of the pixel</returns>
        private Color Shade(Intersection intersection, Scene scene, int depth)
        {
            var direction = intersection.Ray.Direction;
            var position = (intersection.Distance * intersection.Ray.Direction) + intersection.Ray.Start;
            var normal = intersection.Element.Normal(position);
            var reflectDir = direction - (2 * normal.Dot(direction) * normal);

            var ret = Color.DefaultColor;
            ret = ret + this.GetNaturalColor(intersection.Element, position, normal, reflectDir, scene);
            if (depth >= MaxDepth)
            {
                return ret + new Color(.5, .5, .5);
            }

            return ret + this.GetReflectionColor(intersection.Element, position + 0.001 * reflectDir, normal, reflectDir, scene, depth);
        }
示例#4
0
        /// <summary>
        /// Trace a ray through the scene
        /// </summary>
        /// <param name="ray">The ray to test</param>
        /// <param name="scene">The scene description</param>
        /// <param name="depth">The current depth of recursion</param>
        /// <returns>The color of the pixel</returns>
        private Color TraceRay(Ray ray, Scene scene, int depth)
        {
            var intersection = scene.ClosestIntersection(ray);
            if (intersection == null)
            {
                return Color.Background;
            }

            return this.Shade(intersection, scene, depth);
        }
示例#5
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="element"></param>
 /// <param name="position"></param>
 /// <param name="norm"></param>
 /// <param name="rayDirection"></param>
 /// <param name="scene"></param>
 /// <param name="depth"></param>
 /// <returns></returns>
 private Color GetReflectionColor(SceneObject element, Vector position, Vector norm, Vector rayDirection, Scene scene, int depth)
 {
     return element.Surface.Reflectiveness(position) * this.TraceRay(new Ray() { Start = position, Direction = rayDirection }, scene, depth + 1);
 }
示例#6
0
        /// <summary>
        /// Application main method.
        /// </summary>
        /// <param name="args">Command line arguments</param>
        static void Main(string[] args)
        {
            CommandLineArguments cArgs = new CommandLineArguments(args);

            Configuration config = new Configuration();

            var something = new Driven.Metrics.DrivenMetrics.Factory().Create(
                 cArgs.Assemblies.ToArray(),
                 config.Container.ResolveAll<IMetricCalculator>() ,
                     "TestReport",
                 config.Container.Resolve<IReport>());

            something.RunAllMetricsAndGenerateReport();

            CodeStadt.Core.DrivenMetrics.Reporting.ResultOutput results = something.Report.As<Core.DrivenMetrics.Reporting.ResultOutput>();

            if (results != null)
            {
                results.Results.ForEach(x =>
                {
                    Console.WriteLine("Metric: {0}".Formatted(x.Name));
                    Console.WriteLine("");

                    x.ClassResults.ForEach(y =>
                    {
                        Console.WriteLine("  Class: {0}".Formatted(y.Name));
                        Console.WriteLine("");
                        y.MethodResults.ForEach(z =>
                        {
                            Console.WriteLine("    Method: {0} \n\r    Result: {1}".Formatted(z.Name, z.Result));
                            Console.WriteLine("");

                        });
                    });
                });
            }

            // Console.ReadLine();

            Console.WriteLine("Going to try and draw an image :-)");

            // Lets ray trace something
            string raytraceFileName = "raytrace.jpg";
            if (File.Exists(raytraceFileName)) File.Delete(raytraceFileName);

            int width = 600;
            int height = 600;
            var bitmap = new System.Drawing.Bitmap(width, height);

            RayTracer rayTracer = new RayTracer((int x, int y, System.Drawing.Color color) =>
            {
                bitmap.SetPixel(x, y, color);
            });

            var screen = new Screen(width, height);
            var MyScene = new Scene()
            {
                Elements = new List<SceneObject>() {
                                new Plane()
                                {
                                    Norm = new Vector(0, 1, 0),
                                    Point = new Vector(0, -0.5, 0),
                                    Surface = Surfaces.CheckerBoard
                                }
                                //,new Polygon(new List<Vector>(){ new Vector(0,0,0), new Vector(0,1,0), new Vector(1,1,0), new Vector(1,0,0)}, new Vector(0,0,1))
                                //{
                                //    Surface = Surfaces.White
                                //}
                                //,new Polygon(new List<Vector>(){ new Vector(0,0,0), new Vector(0,1,0), new Vector(0,1,1), new Vector(0,0,1)}, new Vector(1,0,0))
                                //{
                                //    Surface = Surfaces.White
                                //}
                                //,new Polygon(new List<Vector>(){ new Vector(0,0,0), new Vector(0,0,1), new Vector(1,0,1), new Vector(1,0,0)}, new Vector(0,1,0))
                                //{
                                //    Surface = Surfaces.White
                                //}
                                //,new Sphere() {
                                //    Center = new Vector(0,1,0),
                                //    Radius = 1,
                                //    Surface = Surfaces.Shiny
                                //},
                                //new Sphere() {
                                //    Center = new Vector(-1,.5,1.5),
                                //    Radius = .5,
                                //    Surface = Surfaces.Shiny
                                //}

                                // FOR TESTING
                                //,new Line(){
                                //    Point = new Vector(0,0,0),
                                //    Direction = new Vector(1,0,0),
                                //    Surface = Surfaces.Green
                                //}
                                //,new Line(){
                                //    Point = new Vector(0,0,0),
                                //    Direction = new Vector(0,1,0),
                                //    Surface = Surfaces.Green
                                //}
                                //,new Line(){
                                //    Point = new Vector(0,0,0),
                                //    Direction = new Vector(0,0,1),
                                //    Surface = Surfaces.Green
                                //}
                                //,new Line(){
                                //    Point = new Vector(1,0,0),
                                //    Direction = new Vector(0,0,1),
                                //    Surface = Surfaces.Green
                                //}

                },
                Lights = new List<Light>() {
                                //new Light() {
                                //    Position = new Vector(-2,2.5,0),
                                //    Color = new Color(.49,.07,.07)
                                //},
                                //new Light() {
                                //    Position = new Vector(1.5,2.5,1.5),
                                //    Color = new Color(.07,.07,.49)
                                //},
                                //new Light() {
                                //    Position = new Vector(1.5,2.5,-1.5),
                                //    Color = new Color(.07,.49,.071)
                                //},
                                //new Light() {
                                //    Position = new Vector(8,5,-6),
                                //    Color = new Color(1,0,0)
                                //},
                                new Light() {
                                    Position = new Vector(8,4,8),
                                    Color = new Color(1,1,1)
                                }},
                Camera = new Camera(new Vector(6, 3, 6), new Vector(0, 0, 0), screen)
                //Camera = new Camera(new Vector(-3, 2, -4), new Vector(-1,0.5,0))
            };

            MyScene.AddModel(new Cube(1, new Vector(0, 0, 0)));

            rayTracer.Render(MyScene);

            bitmap.Save(raytraceFileName);
        }
示例#7
0
        /// <summary>
        /// Get the color of an object at a point of intersection by tracing back to the light sources.
        /// This creates shadows and adds color if the lights are off-white.
        /// </summary>
        /// <param name="element">The object being intersected</param>
        /// <param name="position">The point of intersection on the object</param>
        /// <param name="norm">The normal at the point of intersection</param>
        /// <param name="reflectDirection">The direction of the light reflection off of the surface</param>
        /// <param name="scene">The scene description</param>
        /// <returns>The color of the object due to the scenes lighting</returns>
        private Color GetNaturalColor(SceneObject element, Vector position, Vector norm, Vector reflectDirection, Scene scene)
        {
            var ret = new Color(0, 0, 0);
            foreach (Light light in scene.Lights)
            {
                // Direction from the point of intersction to the light source
                Vector lightDirection = light.Position - position;
                Vector lightUnitVector = lightDirection.Normalise;

                // Perform an intersection test in the direction of the light source to determine if we are in a shadow
                double intersectionDistance = scene.TestRay(new Ray() { Start = position, Direction = lightUnitVector });
                bool isInShadow = !((intersectionDistance > lightDirection.Magnitude) || (intersectionDistance == 0));

                if (!isInShadow)
                {
                    // Check the light is shining on the front of the object.  Use the angle to determine
                    // the brightness of the light.
                    double angleOfIllumination = Vector.Dot(lightUnitVector, norm);
                    Color lightColor = angleOfIllumination > 0 ? angleOfIllumination * light.Color : new Color(0, 0, 0);

                    // Determine of the light is in the direction of a reflection, leading to a specular effect
                    double specular = Vector.Dot(lightUnitVector, reflectDirection.Normalise);

                    // Calculate color of object based on surface qualities
                    Color specularColor = specular > 0 ? Math.Pow(specular, element.Surface.Roughness) * light.Color : new Color(0, 0, 0);
                    ret = ret + (element.Surface.Diffuse(position) * lightColor) + (element.Surface.Specular(position) * specularColor);
                }
            }

            return ret;
        }
示例#8
0
        /// <summary>
        /// Get the color of an object at a point of intersection
        /// </summary>
        /// <param name="intersection">The last point of intersection</param>
        /// <param name="scene">The scene description</param>
        /// <param name="depth">The current depth of recursion</param>
        /// <returns>The color of the pixel</returns>
        private Color Shade(Intersection intersection, Scene scene, int depth)
        {
            // Use Fresnel's law to calculate the direction of the reflected light ray
            // R = 2(N.L)*N - L
            // R = reflection direction
            // N = Normal at point of intersection
            // L = -I
            // I = direction of ray
            var direction = -1 * intersection.Ray.Direction;
            var position = (intersection.Distance * intersection.Ray.Direction) + intersection.Ray.Start;
            var normal = intersection.Element.Normal(position);
            var reflectDir = (2 * normal.Dot(direction) * normal) - direction;

            var ret = Color.DefaultColor;
            ret = ret + this.GetNaturalColor(intersection.Element, position, normal, reflectDir, scene);
            if (depth >= MaxDepth)
            {
                return ret + new Color(.5, .5, .5);
            }

            // The color at this point is equal to the color of the object + any color reflecting on to it
            return ret + this.GetReflectionColor(intersection.Element, position + 0.001 * reflectDir, normal, reflectDir, scene, depth);
        }
示例#9
0
        /// <summary>
        /// Calculate the color being reflected at a point of intersection
        /// </summary>
        /// <param name="element">The object being intersected</param>
        /// <param name="position">The position on the objects surface</param>
        /// <param name="norm">The normal at the point of intersection</param>
        /// <param name="reflectDirection">The direction of the reflected ray</param>
        /// <param name="scene">The scene description</param>
        /// <param name="depth">The current depth of recursion</param>
        /// <returns>The color being reflected</returns>
        private Color GetReflectionColor(SceneObject element, Vector position, Vector norm, Vector reflectDirection, Scene scene, int depth)
        {
            // Only calculate reflected color if the surface is reflective
            var reflectiveness = element.Surface.Reflectiveness(position);
            if (reflectiveness > 0)
            {
                return reflectiveness * this.TraceRay(new Ray() { Start = position, Direction = reflectDirection }, scene, depth + 1);
            }

            return new Color(0, 0, 0);
        }