Esempio n. 1
0
        public BvhNode(List <Hitable> list, double time0, double time1)
        {
            int axis = (int)(FastRandom.RandomDouble() * 3);

            list.Sort(compareHitable(axis));

            if (list.Count == 1)
            {
                left = right = list[0];
            }
            else if (list.Count == 2)
            {
                left  = list[0];
                right = list[1];
            }
            else
            {
                left  = new BvhNode(list.GetRange(0, list.Count / 2), time0, time1);
                right = new BvhNode(list.GetRange(list.Count / 2, list.Count - list.Count / 2), time0, time1);
            }

            AxisAlignedBoundingBox boxLeft, boxRight;

            if (!left.BoundingBox(time0, time1, out boxLeft) || !right.BoundingBox(time0, time1, out boxRight))
            {
                throw new Exception("No Bounding Box in BvhNode Constructor.");
            }

            box = AxisAlignedBoundingBox.SurroundingBox(boxLeft, boxRight);
        }
Esempio n. 2
0
        private void Permute(int[] p, int n)
        {
            for (int i = n - 1; i > 0; i--)
            {
                int target = (int)(FastRandom.RandomDouble() * (i + 1));
                int tmp    = p[i];
                p[i]      = p[target];
                p[target] = tmp;
            }

            return;
        }
Esempio n. 3
0
        private Vec3[] PerlinGenerate()
        {
            Vec3[] p = new Vec3[256];

            for (int i = 0; i < 256; i++)
            {
                p[i] = Vec3.UnitVector(new Vec3(-1 + 2 * FastRandom.RandomDouble(),
                                                -1 + 2 * FastRandom.RandomDouble(),
                                                -1 + 2 * FastRandom.RandomDouble()));
            }

            return(p);
        }
Esempio n. 4
0
        public override bool Scatter(Ray rIn, HitRecord rec, out Vec3 attenuation, out Ray scattered)
        {
            Vec3   outwardNormal = new Vec3();
            Vec3   reflected     = Vec3.Reflect(rIn.Direction(), rec.Normal);
            double niOverNt;

            attenuation = new Vec3(1.0, 1.0, 1.0);
            Vec3   refracted = new Vec3();
            double reflectProb;
            double cosine;

            if (Vec3.Dot(rIn.Direction(), rec.Normal) > 0)
            {
                outwardNormal = -rec.Normal;
                niOverNt      = _refIndex;
                cosine        = _refIndex * Vec3.Dot(rIn.Direction(), rec.Normal) / rIn.Direction().Length();
            }
            else
            {
                outwardNormal = rec.Normal;
                niOverNt      = 1.0 / _refIndex;
                cosine        = -Vec3.Dot(rIn.Direction(), rec.Normal) / rIn.Direction().Length();
            }

            if (Vec3.Refract(rIn.Direction(), outwardNormal, niOverNt, out refracted))
            {
                reflectProb = Schlick(cosine, _refIndex);
            }
            else
            {
                reflectProb = 1.0;
            }

            if (FastRandom.RandomDouble() < reflectProb)
            {
                scattered = new Ray(rec.P, reflected, rIn.Time());
            }
            else
            {
                scattered = new Ray(rec.P, refracted, rIn.Time());
            }

            return(true);
        }
Esempio n. 5
0
        public override Hitable GetObjects()
        {
            List <Hitable> list = new List <Hitable>();

            var checker = new CheckerTexture(new ConstantTexture(new Vec3(0.2, 0.3, 0.1)), new ConstantTexture(new Vec3(0.9, 0.9, 0.9)));

            list.Add(new Sphere(new Vec3(0.0, -1000.0, 0.0), 1000, new Lambertian(checker)));

            for (int a = -11; a < 11; a++)
            {
                for (int b = -11; b < 11; b++)
                {
                    double chooseMaterial = FastRandom.RandomDouble();
                    Vec3   center         = new Vec3(a + 0.9 * FastRandom.RandomDouble(), 0.2, b + 0.9 * FastRandom.RandomDouble());

                    if ((center - new Vec3(4.0, 0.2, 0.0)).Length() > 0.9)
                    {
                        if (chooseMaterial < 0.8) // diffuse
                        {
                            list.Add(new MovingSphere(center, center + new Vec3(0.0, 0.5 * FastRandom.RandomDouble(), 0.0), 0.0, 1.0, 0.2, new Lambertian(new ConstantTexture(new Vec3(FastRandom.RandomDouble() * FastRandom.RandomDouble(), FastRandom.RandomDouble() * FastRandom.RandomDouble(), (FastRandom.RandomDouble() * FastRandom.RandomDouble()))))));
                        }
                        else if (chooseMaterial < 0.95) // metal
                        {
                            list.Add(new Sphere(center, 0.2, new Metal(new Vec3(0.5 * (1.0 + FastRandom.RandomDouble()), 0.5 * (1.0 + FastRandom.RandomDouble()), 0.5 * (1.0 + FastRandom.RandomDouble())), 0.5 * FastRandom.RandomDouble())));
                        }
                        else // dielectric
                        {
                            list.Add(new Sphere(center, 0.2, new Dielectric(1.5)));
                        }
                    }
                }
            }

            list.Add(new Sphere(new Vec3(0.0, 1.0, 0.0), 1.0, new Dielectric(1.5)));
            list.Add(new Sphere(new Vec3(-4.0, 1.0, 0.0), 1.0, new Lambertian(new ConstantTexture(new Vec3(0.4, 0.2, 0.1)))));
            list.Add(new Sphere(new Vec3(4.0, 1.0, 0.0), 1.0, new Metal(new Vec3(0.7, 0.6, 0.5), 0.0)));

            return((Hitable) new BvhNode(list, 0.0, 1.0));
        }
Esempio n. 6
0
        static void Main(string[] args)
        {
            // Seed RNG
            FastRandom.Initialize((uint)new Random().Next());

            string homePath = (Environment.OSVersion.Platform == PlatformID.Unix ||
                               Environment.OSVersion.Platform == PlatformID.MacOSX)
                ? Environment.GetEnvironmentVariable("HOME")
                : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
            var outputFileName = Path.Combine(new string[] { homePath, "output.jpg" });

            var nx = 600;  // Horizontal resolution
            var ny = 400;  // Vertical resolution
            var ns = 150;  // Antialising samples per pixel

            Console.WriteLine($"Width:\t{nx}");
            Console.WriteLine($"Height:\t{ny}");
            Console.WriteLine($"Antialiasing:\t{ns}");
            Console.WriteLine();

            var scene = new Scenes.CornellBox();
            var world = scene.GetObjects();
            var cam   = scene.GetCamera((double)nx / (double)ny);

            byte[] outputBytes = new byte[4 * nx * ny];

            Console.WriteLine("Rendering...");
            UpdateProgress(ny, 0);

            var linesRendered = 0;

            Parallel.For(0, ny, j =>
            {
                for (int i = 0; i < nx; i++)
                {
                    Vec3 col = new Vec3(0.0, 0.0, 0.0);

                    for (int s = 0; s < ns; s++)
                    {
                        double u = (i + FastRandom.RandomDouble()) / nx;
                        double v = (j + FastRandom.RandomDouble()) / ny;

                        Ray r = cam.GetRay(u, v);
                        col  += Color(r, world, 0);
                    }

                    col /= ns;
                    col  = new Vec3(Math.Sqrt(col[0]), Math.Sqrt(col[1]), Math.Sqrt(col[2]));

                    outputBytes[4 * ((ny - 1 - j) * nx) + (4 * i)]     = (byte)(255.9 * col[0]);
                    outputBytes[4 * ((ny - 1 - j) * nx) + (4 * i) + 1] = (byte)(255.9 * col[1]);
                    outputBytes[4 * ((ny - 1 - j) * nx) + (4 * i) + 2] = (byte)(255.9 * col[2]);
                    outputBytes[4 * ((ny - 1 - j) * nx) + (4 * i) + 3] = 255;
                }

                linesRendered++;
                UpdateProgress(ny, linesRendered);
            });

            Console.WriteLine("\nRendering completed, writing to file...");

            var outputImg = Image.LoadPixelData <Byte4>(outputBytes, nx, ny);

            outputImg.Save(outputFileName);

            Console.WriteLine("Saving completed, press any key to exit.");
            Console.ReadKey();
        }