コード例 #1
0
ファイル: RandomMarbles.cs プロジェクト: Winterfr0st/rtracer
        private HitableList GenerateWorld(Random rng)
        {
            UnitSphereUniformSampler sphereSampler = new UnitSphereUniformSampler(rng);

            List <IHitable> objects = new List <IHitable>();

            // Add the main earth object
            IMaterial earthMaterial = new Lambertian(new Vector3(0.5, 0.5, 0.5), sphereSampler);

            objects.Add(new Sphere(new Vector3(0, -1000, 0), 1000, earthMaterial));

            // Generate random objects
            Vector3 temp = new Vector3(4, 0.2, 0);

            for (int a = -11; a < 11; ++a)
            {
                for (int b = -11; b < 11; ++b)
                {
                    double  chooseMat = rng.NextDouble();
                    Vector3 center    = new Vector3(a + 0.9 * rng.NextDouble(), 0.2, b + 0.9 * rng.NextDouble());
                    if ((center - temp).Length() > 0.9)
                    {
                        // 80% chance to choose diffuse
                        if (chooseMat < 0.8)
                        {
                            double red   = rng.NextDouble() * rng.NextDouble();
                            double green = rng.NextDouble() * rng.NextDouble();
                            double blue  = rng.NextDouble() * rng.NextDouble();

                            var randomDiffuseMaterial = new Lambertian(
                                new Vector3(red, green, blue),
                                sphereSampler);
                            objects.Add(new Sphere(center, 0.2, randomDiffuseMaterial));
                        }
                        else if (chooseMat < 0.95)
                        {
                            // 15% chance for metal material
                            double red         = 0.5 * (1 + rng.NextDouble());
                            double green       = 0.5 * (1 + rng.NextDouble());
                            double blue        = 0.5 * (1 + rng.NextDouble());
                            double fuzz        = 0.5 * rng.NextDouble();
                            var    randomMetal = new Metal(new Vector3(red, green, blue), fuzz, sphereSampler);
                            objects.Add(new Sphere(center, 0.2, randomMetal));
                        }
                        else
                        {
                            // 5% chance for dielectric
                            objects.Add(new Sphere(center, 0.2, new Dielectric(1.5, rng)));
                        }
                    }
                }
            }

            objects.Add(new Sphere(new Vector3(0, 1, 0), 1.0, new Dielectric(1.5, rng)));
            objects.Add(new Sphere(new Vector3(-4, 1, 0), 1.0, new Lambertian(new Vector3(0.4, 0.2, 0.1), sphereSampler)));
            objects.Add(new Sphere(new Vector3(4, 1, 0), 1.0, new Metal(new Vector3(0.7, 0.6, 0.5), 0.0, sphereSampler)));

            return(new HitableList(objects));
        }
コード例 #2
0
ファイル: Metal.cs プロジェクト: Winterfr0st/rtracer
 public Metal(Vector3 a, double fuzz, UnitSphereUniformSampler sampler)
 {
     this.albedo  = a;
     this.fuzz    = fuzz;
     this.sampler = sampler;
 }
コード例 #3
0
ファイル: Lambertian.cs プロジェクト: Winterfr0st/rtracer
 public Lambertian(Vector3 albedo, UnitSphereUniformSampler sampler)
 {
     this.albedo  = albedo;
     this.sampler = sampler;
 }
コード例 #4
0
        public void RenderScene()
        {
            int nx = 800;
            int ny = 400;
            int ns = 100;

            var lowerLeftCorner = new Vector3(-2.0, -1.0, -1.0);
            var horizontal      = new Vector3(4.0, 0.0, 0.0);
            var vertical        = new Vector3(0.0, 2.0, 0.0);
            var origin          = new Vector3(0.0, 0.0, 0.0);

            Random rng = new Random();
            UnitSphereUniformSampler sphereSampler = new UnitSphereUniformSampler(rng);
            UnitCircleUniformSampler circleSampler = new UnitCircleUniformSampler(rng);

            IMaterial mat1 = new Lambertian(new Vector3(0.1, 0.2, 0.5), sphereSampler);
            IMaterial mat2 = new Lambertian(new Vector3(0.8, 0.8, 0.0), sphereSampler);
            IMaterial mat3 = new Metal(new Vector3(0.8, 0.6, 0.2), 0.3, sphereSampler);
            IMaterial mat4 = new Dielectric(1.5, rng);

            List <IHitable> objects = new List <IHitable>(4);

            objects.Add(new Sphere(new Vector3(0, 0, -1), 0.5, mat1));
            objects.Add(new Sphere(new Vector3(0, -100.5, -1), 100, mat2));
            objects.Add(new Sphere(new Vector3(1, 0, -1), 0.5, mat3));
            objects.Add(new Sphere(new Vector3(-1, 0, -1), 0.5, mat4));
            objects.Add(new Sphere(new Vector3(-1, 0, -1), -0.45, mat4));

            HitableList world    = new HitableList(objects);
            Vector3     lookFrom = new Vector3(-2, 2, 1);
            Vector3     lookAt   = new Vector3(0, 0, -1);
            Camera      camera   = new Camera(
                circleSampler,
                lookFrom,
                lookAt,
                new Vector3(0, 1, 0),
                90.0 * Math.PI / 180.0,
                (double)nx / (double)ny,
                0.2,
                (lookAt - lookFrom).Length());

            Random random = new Random();

            // Create folder to output frames
            if (!Directory.Exists("ThreeSpheres"))
            {
                Directory.CreateDirectory("ThreeSpheres");
            }

            Sensor sensor   = new Sensor(nx, ny, new SqrtColorSpace(), RGBColor.Black);
            int    frameNum = 0;

            for (int s = 0; s < ns; ++s)
            {
                for (int j = ny - 1; j >= 0; --j)
                {
                    for (int i = 0; i < nx; i++)
                    {
                        double u = (i + random.NextDouble()) / nx;
                        double v = (j + random.NextDouble()) / ny;

                        Ray3    r     = new Ray3(camera.GetRay(u, v));
                        Vector3 color = Program.Color(r, world, 0);
                        sensor.AddSample(i, j, new RGBColor(color[0], color[1], color[2]));
                    }
                }

                if (s % (ns / 10) == 0)
                {
                    // Output 1 frame with current number of samples
                    sensor.WritePPMFile($"ThreeSpheres\\frame_{frameNum}.ppm").Wait();
                    frameNum++;
                }

                Console.Write("\r{0}", s);
            }

            sensor.WritePPMFile("finalOutput.ppm").Wait();
        }