public static Vector3 RandomInUnitSphere(this ImSoRandom random)
        {
            var p = new Vector3();

            do
            {
                p = 2.0f * new Vector3(random.NextFloat(), random.NextFloat(), random.NextFloat()) - new Vector3(1, 1, 1);
            } while (p.LengthSquared() >= 1.0f);
            return(p);
        }
        public static Vector3 RandomInUnitDisk(this ImSoRandom random)
        {
            var p = new Vector3();

            do
            {
                p = 2.0f * new Vector3(random.NextFloat(), random.NextFloat(), 0) - new Vector3(1, 1, 0);
            } while (Vector3.Dot(p, p) >= 1.0f);
            return(p);
        }
Ejemplo n.º 3
0
        public static (List <IHitable>, Camera) RandomScene(ImSoRandom rnd, int nx, int ny)
        {
            var world = new List <IHitable>();

            var texture = new CheckerTexture(new ConstantTexture(0.2f, 0.3f, 0.1f), new ConstantTexture(0.9f, 0.9f, 0.9f));

            world.Add(new Sphere(new Vector3(0, -1000f, 0), 1000, new Lambertian(texture)));

            for (int a = -11; a < 11; a++)
            {
                for (int b = -11; b < 11; b++)
                {
                    float choose_mat = rnd.NextFloat();
                    var   center     = new Vector3(a + 0.9f * rnd.NextFloat(), 0.2f, b + 0.9f * rnd.NextFloat());
                    if ((center - new Vector3(4, 0.2f, 0)).Length() > 0.9)
                    {
                        if (choose_mat < 0.8)
                        {  // diffuse
                            world.Add(new MovingSphere(center, center + new Vector3(0, 0.5f * rnd.NextFloat(), 0), 0.0f, 1.0f, 0.2f, new Lambertian(new ConstantTexture(rnd.NextFloat() * rnd.NextFloat(), rnd.NextFloat() * rnd.NextFloat(), rnd.NextFloat() * rnd.NextFloat()))));
                            //world.Add(new Sphere(center, 0.2f, new Lambertian(new Vector3(rnd.NextFloat() * rnd.NextFloat(), rnd.NextFloat() * rnd.NextFloat(), rnd.NextFloat() * rnd.NextFloat()))));
                        }
                        else if (choose_mat < 0.95)
                        { // metal
                            world.Add(new Sphere(center, 0.2f,
                                                 new Metal(new Vector3(0.5f * (1 + rnd.NextFloat()), 0.5f * (1 + rnd.NextFloat()), 0.5f * (1 + rnd.NextFloat())), 0.5f * rnd.NextFloat())));
                        }
                        else
                        {  // glass
                            world.Add(new Sphere(center, 0.2f, new Dialectric(1.5f)));
                        }
                    }
                }
            }

            world.Add(new Sphere(new Vector3(0, 1, 0), 1.0f, new Dialectric(1.5f)));
            world.Add(new Sphere(new Vector3(-4, 1, 0), 1.0f, new Lambertian(new ConstantTexture(0.4f, 0.2f, 0.1f))));
            world.Add(new Sphere(new Vector3(4, 1, 0), 1.0f, new Metal(new Vector3(0.7f, 0.6f, 0.5f), 0f)));

            world.Add(new Sphere(new Vector3(0, 0, 0), 20.0f, new DiffuseLight(new ConstantTexture(new Vector3(1, 1, 1)))));


            var lookFrom    = new Vector3(13, 2, 3);
            var lookAt      = new Vector3(0, 0, 0);
            var distToFocus = 10;
            var aperture    = 0.1f;

            var cam = new Camera(lookFrom, lookAt, new Vector3(0, 1, 0), 20, (float)nx / (float)ny, aperture, distToFocus, 0.0f, 1.0f);

            return(world, cam);
        }
Ejemplo n.º 4
0
        public Ray GetRay(float u, float v, ImSoRandom rnd)
        {
            var   rd     = LensRadius * rnd.RandomInUnitDisk();
            var   offset = U * rd.X + V * rd.Y;
            float time   = Time0 + rnd.NextFloat() * (Time1 - Time0);

            return(new Ray(Origin + offset, LowerLeftCorner + u * Horizontal + v * Vertical - Origin - offset, time));
        }
Ejemplo n.º 5
0
        public static (List <IHitable>, Camera) PoolScene(ImSoRandom rnd, int nx, int ny)
        {
            var world = new List <IHitable>();

            world.Add(new Sphere(new Vector3(0, -1000f, 0), 1000, new Lambertian(new ConstantTexture(0.33f, 0.67f, 0.0f))));
            var red    = new ConstantTexture(0.68f, 0.13f, 0.16f);
            var yellow = new ConstantTexture(1f, 0.74f, 0.13f);
            var black  = new ConstantTexture(0.14f, 0.07f, 0.07f);
            var white  = new ConstantTexture(1f, 1f, 0.9f);

            for (var a = 1f; a <= 5; a += 1f)
            {
                var counter = 0 - a;
                for (var b = 0f; b < a; b += 1f)
                {
                    var center = new Vector3(a * 0.9f - 5f, 0.5f, a / 2f - b - 0.5f);
                    var colour = counter % 2 == 0 ? red : yellow;
                    if (a == 3 && b == 1)
                    {
                        colour = black;
                    }
                    if (a == 3 && b == 2)
                    {
                        colour = red;
                    }
                    if (a == 5 && b == 4)
                    {
                        colour = red;
                    }
                    world.Add(new Sphere(center, 0.45f,
                                         new Lambertian(colour)));
                    world.Add(new Sphere(center, 0.5f,
                                         new Dialectric(1.5f)));
                    counter++;
                }
            }

            var cueCenter  = new Vector3(-6, 0.5f, 0);
            var cueCenter1 = cueCenter + new Vector3(0.75f * rnd.NextFloat(), 0, 0);

            world.Add(new MovingSphere(cueCenter, cueCenter1, 0.0f, 1.0f, 0.5f,
                                       new Dialectric(1.5f)));
            world.Add(new MovingSphere(cueCenter, cueCenter1, 0.0f, 1.0f, 0.45f,
                                       new Lambertian(white)));

            world.Add(new RectXZ(-3, 3, -2, 2, 5, new DiffuseLight(new ConstantTexture(new Vector3(15, 15, 15)))));

            var lookFrom    = new Vector3(-9, 3.5f, 12);
            var lookAt      = new Vector3(-3, 0, 0);
            var distToFocus = (lookFrom - new Vector3(-6, 0.5f, 0)).Length();
            var aperture    = 0.5f;

            var cam = new Camera(lookFrom, lookAt, new Vector3(0, 1, 0), 20, (float)nx / (float)ny, aperture, distToFocus, 0.0f, 1.0f);

            return(world, cam);
        }
Ejemplo n.º 6
0
        private static void RenderRow(Image <Rgba32> image, IHitable[] wl, Camera cam, int j, int nx, int ny, int ns, ImSoRandom rnd, ConcurrentDictionary <int, int> processedRows, ref uint rayCount)
        {
            var index   = ny - 1 - j;
            var rowSpan = image.GetPixelRowSpan(index);

            for (int i = 0; i < nx; i++)
            {
                var col = new Vector3(0);

                for (var s = 0; s < ns; s++)
                {
                    float u = ((float)i + rnd.NextFloat()) / (float)nx;
                    float v = ((float)j + rnd.NextFloat()) / (float)ny;
                    var   r = cam.GetRay(u, v, rnd);
                    col += Color(r, wl, 0, rnd, ref rayCount);
                }

                col /= (float)ns;
                col  = new Vector3((float)Math.Sqrt(col.X), (float)Math.Sqrt(col.Y), (float)Math.Sqrt(col.Z));

                rowSpan[i] = new Rgba32(col);
            }
            processedRows.TryAdd(j, Thread.CurrentThread.ManagedThreadId);
        }
        public override bool Scatter(Ray rayIn, HitRecord rec, out Vector3 attenuation, out Ray scattererd, ImSoRandom random)
        {
            Vector3 reflected = Vector3.Reflect(rayIn.Direction, rec.Normal);

            attenuation = new Vector3(1.0f);

            Vector3 outward_normal;
            float   niOverNt;
            float   cosine;

            if (Vector3.Dot(rayIn.Direction, rec.Normal) > 0)
            {
                outward_normal = -rec.Normal;
                niOverNt       = _refIndex;
                cosine         = _refIndex * Vector3.Dot(rayIn.Direction, rec.Normal) / rayIn.Direction.Length();
            }
            else
            {
                outward_normal = rec.Normal;
                niOverNt       = 1.0f / _refIndex;
                cosine         = -Vector3.Dot(rayIn.Direction, rec.Normal) / rayIn.Direction.Length();
            }

            Vector3 refracted;
            float   reflectProb;

            if (Refract(rayIn.Direction, outward_normal, niOverNt, out refracted))
            {
                reflectProb = Schlick(cosine, _refIndex);
            }
            else
            {
                reflectProb = 1.0f;
            }

            if (random.NextFloat() < reflectProb)
            {
                scattererd = new Ray(rec.P, reflected, rayIn.Time);
            }
            else
            {
                scattererd = new Ray(rec.P, refracted, rayIn.Time);
            }
            return(true);
        }
 public static Vector3 RandomVector(this ImSoRandom random)
 {
     return(new Vector3(10 + random.NextFloat() * 400f, 10 + random.NextFloat() * 400f, 10 + random.NextFloat() * 400f));
 }