예제 #1
0
        public MainWindow()
        {
            InitializeComponent();

            const int image_width       = 400;
            const int image_height      = 236;
            double    aspect_ratio      = (double)image_width / (double)image_height;
            const int samples_per_pixel = 10;
            const int max_depth         = 50;

            //World
            var world = new hittable_list();

            var material  = new Metal(new Vektor(.7, .7, .7), 0.7);
            var material1 = new Metal(new Vektor(1, 0.32, 0.36), 0);
            var material2 = new Metal(new Vektor(0.90, 0.76, 0.46), 0);
            var material3 = new Metal(new Vektor(0.65, 0.77, 0.97), 0);
            var material4 = new Metal(new Vektor(0.90, 0.90, 0.90), 0);

            world.Add(new sphere(new Vektor(0.0, -10004, -20), 10000, material));
            world.Add(new sphere(new Vektor(0, 0, -20), 4, material1));
            world.Add(new sphere(new Vektor(5, -1, -15), 2, material2));
            world.Add(new sphere(new Vektor(5, 0, -25), 3, material3));
            world.Add(new sphere(new Vektor(-5.5, 0, -15), 3, material4));

            //Camera

            Vektor lookfrom      = new Vektor(0, 0, 0);
            Vektor lookat        = new Vektor(0, 0, -1);
            Vektor vup           = new Vektor(0, 1, 0);
            var    dist_to_focus = 10;
            var    aperture      = 0.1;

            Camera cam = new Camera(lookfrom, lookat, vup, 50, aspect_ratio, aperture, dist_to_focus);

            Vektor[,] vArr = new Vektor[image_height, image_width];
            Bitmap bmp = new Bitmap(image_width, image_height);

            Parallel.For(0, image_height, j =>
            {
                for (int i = 0; i < image_width; i++)
                {
                    Vektor pixel_color = new Vektor(0, 0, 0);
                    for (int s = 0; s < samples_per_pixel; s++)
                    {
                        var u        = ((double)i + Mathe.random_double()) / (image_width - 1);
                        var v        = ((double)j + Mathe.random_double()) / (image_height - 1);
                        ray r        = cam.get_ray(u, v);
                        pixel_color += ray.ray_color(r, world, max_depth);
                    }
                    vArr[j, i] = pixel_color;
                }
            });

            for (int j = 0; j < image_height; j++)
            {
                for (int i = 0; i < image_width; i++)
                {
                    bmp.SetPixel(i, (j - (image_height - 1)) * -1, Vektor.toColor(vArr[j, i], samples_per_pixel));
                }
            }

            image.Source = BitmapToImageSource(bmp);
        }
예제 #2
0
        public static Model FromObjFile(string path, IMaterial defaultMaterial)
        {
            var root         = Path.GetDirectoryName(path);
            var model        = new Model();
            var lastMaterial = defaultMaterial;

            using (var file = new FileStream(path, FileMode.Open))
                using (var reader = new StreamReader(file))
                {
                    while (!reader.EndOfStream)
                    {
                        var line = reader.ReadLine();
                        // dismiss blank space
                        if (string.IsNullOrWhiteSpace(line))
                        {
                            continue;
                        }

                        // use comment to inform texture
                        if (line.StartsWith("#m"))
                        {
                            var words       = line.Split(' ');
                            var materialStr = words[1];
                            switch (materialStr)
                            {
                            case "metal":
                            {
                                var arg1 = float.Parse(words[2]);
                                var arg2 = words[3];
                                Debug.Assert(root != null, nameof(root) + " != null");
                                var imagePath = Path.Combine(root, arg2);
                                if (!Directory.Exists(imagePath))
                                {
                                    throw new FileNotFoundException(imagePath);
                                }
                                lastMaterial = new Metal(new BitmapTexture(imagePath), arg1);
                                break;
                            }
                            }
                        }

                        // dismiss comment
                        if (line.StartsWith("#"))
                        {
                            continue;
                        }

                        var seps    = line.Split(' ');
                        var pattern = seps[0];
                        if (pattern == "f")
                        {
                            // define face
                            // only get index of vertex
                            seps = seps.Select(it =>
                            {
                                var p = it.IndexOf("/", StringComparison.Ordinal);
                                return(p == -1 ? it : it.Substring(0, p));
                            }).ToArray();
                            switch (seps.Length)
                            {
                            case 4:
                            {
                                var arg1 = int.Parse(seps[1]) - 1;
                                var arg2 = int.Parse(seps[2]) - 1;
                                var arg3 = int.Parse(seps[3]) - 1;
                                model.AddFace(arg1, arg2, arg3, lastMaterial);
                                break;
                            }

                            case 5:
                            {
                                var arg1 = int.Parse(seps[1]) - 1;
                                var arg2 = int.Parse(seps[2]) - 1;
                                var arg3 = int.Parse(seps[3]) - 1;
                                var arg4 = int.Parse(seps[4]) - 1;
                                model.AddFace(arg1, arg2, arg3, lastMaterial);
                                model.AddFace(arg1, arg2, arg4, lastMaterial);
                                break;
                            }

                            default:
                                throw new InvalidDataException(path);
                            }
                        }
                        else if (pattern == "v")
                        {
                            // is vertex
                            var arg1 = float.Parse(seps[1]);
                            var arg2 = float.Parse(seps[2]);
                            var arg3 = float.Parse(seps[3]);
                            model.AddVertex(arg1, arg2, arg3);
                        }
                    }
                }
            return(model);
        }