Example #1
0
        private static HittableList RandomScene()
        {
            HittableList world = new HittableList();

            Material groundMat = new Lambertian(new Colour(0.5f, 0.5f, 0.5f));

            world.Add(new Sphere(new Point3(0, -1000, 0), 1000, groundMat));

            for (int a = -11; a < 11; a++)
            {
                for (int b = -11; b < 11; b++)
                {
                    double chooseMat = random.NextDouble();
                    Point3 centre    = new Point3((float)(a + 0.9 * random.NextDouble()), 0.2f, (float)(b + 0.9 * random.NextDouble()));

                    if ((centre - new Point3(4, 0.2f, 0)).Length() > 0.9f)
                    {
                        Material sphereMat;
                        float    radius = random.NextDouble() / 10f + 0.15f;
                        centre.Y = radius;
                        if (chooseMat < 0.8f)
                        {
                            // Diffuse
                            Colour albedo = RandVector(0, 1) * RandVector(0, 1);
                            sphereMat = new Lambertian(albedo);
                            world.Add(new Sphere(centre, radius, sphereMat));
                        }
                        else if (chooseMat < 0.95)
                        {
                            // Metal
                            Colour albedo = RandVector(0.5f, 1);
                            float  fuzz   = (float)(random.NextDouble() / 2);
                            sphereMat = new Metal(albedo, fuzz);
                            world.Add(new Sphere(centre, radius, sphereMat));
                        }
                        else
                        {
                            // Glass
                            sphereMat = new Dielectric(RandFloat(1.3f, 1.7f));
                            world.Add(new Sphere(centre, radius, sphereMat));
                        }
                    }
                }
            }

            Material material1 = new Dielectric(1.5f);

            world.Add(new Sphere(new Point3(0, 1, 0), 1.0f, material1));

            Material material2 = new Lambertian(new Colour(0.4f, 0.2f, 0.1f));

            world.Add(new Sphere(new Point3(-4, 1, 0), 1.0f, material2));

            Material material3 = new Metal(new Colour(0.7f, 0.6f, 0.5f), 0.0f);

            world.Add(new Sphere(new Point3(4, 1, 0), 1.0f, material3));

            return(world);
        }
Example #2
0
        static void Main()
        {
            // Image
            float aspectRatio     = 16f / 9f;
            int   imgWidth        = (int)(1920 / 1.5);
            int   imgHeight       = (int)(imgWidth / aspectRatio);
            int   samplesPerPixel = 64;
            int   maxDepth        = 50;

            imgStrs = new List <string> [imgHeight + 1];

            // World
            HittableList world = RandomScene();

            // Camera
            Point3 lFrom       = new Point3(13, 2, 3);
            Point3 lAt         = new Point3(0, 0, 0);
            Point3 vUp         = new Point3(0, 1, 0);
            float  aperature   = 0.1f;
            float  distToFocus = 10;           // (lFrom - lAt).Length();

            cam = new Camera(lFrom, lAt, vUp, 20f, aspectRatio, aperature, distToFocus);

            int count = 0;

            imgStrs[0] = new List <string> {
                $"P3\n{imgWidth} {imgHeight}\n255\n"
            };
            Parallel.For(0, imgHeight, j =>
            {
                count++;
                Console.Write($"\rScanlines remaining: {imgHeight - count} ");
                imgStrs[imgHeight - j] = CalcRow(imgWidth, imgHeight, samplesPerPixel, maxDepth, world, j);
            });


            Console.WriteLine("\nWriting image...");
            using (FileStream fs = new FileStream(Directory.GetCurrentDirectory() + "\\output.ppm", FileMode.Create))
            {
                StreamWriter sr = new StreamWriter(fs);
                foreach (List <string> ls in imgStrs)
                {
                    foreach (string s in ls)
                    {
                        sr.Write(s);
                    }
                }
                sr.Close();
            }
            Console.WriteLine("Done!");
        }
Example #3
0
        private static List <string> CalcRow(int imgWidth, int imgHeight, int samplesPerPixel, int maxDepth, HittableList world, int j)
        {
            List <string> res = new List <string>();

            for (int i = 0; i < imgWidth; i++)
            {
                Colour pixelColour = Colour.Zero;
                for (int s = 0; s < samplesPerPixel; s++)
                {
                    float u = (float)((i + random.NextDouble()) / (imgWidth - 1));
                    float v = (float)((j + random.NextDouble()) / (imgHeight - 1));
                    Ray   r = cam.GetRay(u, v);
                    pixelColour += RayColour(r, world, maxDepth);
                }
                WriteColour(pixelColour, samplesPerPixel, res);
            }
            return(res);
        }