Пример #1
0
        // if no object is hit, draw a gradient
        static Vector3 color(Ray r, Hitable world, int depth)
        {
            hit_record rec = new hit_record();

            // see if an object is hit
            if (world.hit(r, 0.001f, float.MaxValue, ref rec))
            {
                // shade the indicated point
                Ray     scattered   = new Ray();
                Vector3 attenuation = new Vector3();
                if (depth < 50 && rec.mat.scatter(r, rec, ref attenuation, ref scattered))
                {
                    return(attenuation * color(scattered, world, depth + 1));
                }
                else
                {
                    // reached our max depth, don't render any further
                    return(new Vector3());
                }
            }
            else
            {
                // no object hit, draw the background
                Vector3 unit_dir = r.direction().unit_vector();
                float   t        = 0.5f * (unit_dir.y() + 1.0f);
                return((new Vector3(1.0f, 1.0f, 1.0f)) * (1.0f - t) + (new Vector3(0.5f, 0.7f, 1.0f) * t));
            }
        }
Пример #2
0
        public Ray getRay(float s, float t)
        {
            Vector3 rd     = lens_radius * Utils.random_in_unit_disk();
            Vector3 offset = u * rd.x() + v * rd.y();
            float   time   = (float)Utils.rnd.NextDouble() * (time0 - time1);

            return(new Ray(origin + offset, lower_left + s * horizontal + t * vertical - origin - offset, time));
        }
Пример #3
0
        public bool hit(Ray r, float tmin, float tmax)
        {
            float t0 = Utils.fmin((_min.x() - r.origin().x()) / r.direction().x(),
                                  (_max.x() - r.origin().x()) / r.direction().x());
            float t1 = Utils.fmax((_min.x() - r.origin().x()) / r.direction().x(),
                                  (_max.x() - r.origin().x()) / r.direction().x());

            tmin = Utils.fmax(t0, tmin);
            tmax = Utils.fmin(t1, tmax);

            if (tmax <= tmin)
            {
                return(false);
            }

            t0 = Utils.fmin((_min.y() - r.origin().y()) / r.direction().y(),
                            (_max.y() - r.origin().y()) / r.direction().y());
            t1 = Utils.fmax((_min.y() - r.origin().y()) / r.direction().y(),
                            (_max.y() - r.origin().y()) / r.direction().y());

            tmin = Utils.fmax(t0, tmin);
            tmax = Utils.fmin(t1, tmax);

            if (tmax <= tmin)
            {
                return(false);
            }

            t0 = Utils.fmin((_min.z() - r.origin().z()) / r.direction().z(),
                            (_max.z() - r.origin().z()) / r.direction().z());
            t1 = Utils.fmax((_min.y() - r.origin().y()) / r.direction().y(),
                            (_max.z() - r.origin().z()) / r.direction().z());

            tmin = Utils.fmax(t0, tmin);
            tmax = Utils.fmin(t1, tmax);

            if (tmax <= tmin)
            {
                return(false);
            }

            return(true);
        }
Пример #4
0
        public override Vector3 value(float u, float v, ref Vector3 p)
        {
            float sins = (float)(Math.Sin(p.x() * size) * Math.Sin(p.y() * size) * Math.Sin(p.z() * size));

            if (sins > 0.0f)
            {
                return(even.value(u, v, ref p));
            }
            else
            {
                return(odd.value(u, v, ref p));
            }
        }
Пример #5
0
        public float noise(Vector3 p)
        {
            float u = p.x() - (float)Math.Floor(p.x());
            float v = p.y() - (float)Math.Floor(p.y());
            float w = p.z() - (float)Math.Floor(p.z());
            int   i = (int)Math.Floor(p.x());
            int   j = (int)Math.Floor(p.y());
            int   k = (int)Math.Floor(p.z());

            Vector3[,,] c = new Vector3[2, 2, 2];
            for (int di = 0; di < 2; di++)
            {
                for (int dj = 0; dj < 2; dj++)
                {
                    for (int dk = 0; dk < 2; dk++)
                    {
                        c [di, dj, dk] = ran_vecs [perm_x [(i + di) & 255] ^ perm_y [(j + dj) & 255] ^ perm_z [(k + dk) & 255]];
                    }
                }
            }

            return(Utils.trilinear_interpolation(c, u, v, w));
        }
Пример #6
0
        public static void Main(string[] args)
        {
            // output to a ppm file
            Console.Write("P3\n" + nx + " " + ny + " " + "\n255\n");

            // create the world
            List <Hitable> world = new List <Hitable>();

            world.Add(new Moving_Sphere(new Vector3(0.0f, 0.0f, 0.0f),
                                        new Vector3(0.0f, 0.0f, -2.0f),
                                        0.0f,
                                        10.0f,
                                        0.5f,
                                        new Lambertian(new Const_Texture(new Vector3(0.137f, 0.467f, 1.0f)))));
            world.Add(new Sphere(new Vector3(1.0f, 0.0f, -1.0f),
                                 0.5f,
                                 new Dielectric(1.5f)));
            world.Add(new Sphere(new Vector3(1.0f, 0.0f, -1.0f),
                                 -0.3f,
                                 new Dielectric(1.5f)));
            world.Add(new Sphere(new Vector3(-1.0f, 0.0f, -1.0f),
                                 0.5f,
                                 new Metal(new Noise(10.0f))));
            world.Add(new Sphere(new Vector3(0.0f, -100.5f, -1.0f),
                                 100.0f,
                                 new Lambertian(new Marble(new Vector3(0.0f, 0.8f, 0.0f), 5.0f))));

            BVH_Node tree = new BVH_Node(world, 0.0f, 10.0f);

            // init the camera
            Vector3 lookfrom      = new Vector3(3.0f, 2.0f, 2.0f);
            Vector3 lookat        = new Vector3(0.0f, 0.0f, -1.0f);
            float   dist_to_focus = (lookfrom - lookat).length();
            float   apeture       = 0.5f;
            Camera  cam           = new Camera(lookfrom,
                                               lookat,
                                               new Vector3(0.0f, 1.0f, 0.0f),
                                               40.0f,
                                               (float)nx / (float)ny,
                                               apeture,
                                               dist_to_focus,
                                               0.0f,
                                               10.0f);

            for (int i = ny - 1; i >= 0; i--)
            {
                for (int j = 0; j < nx; j++)
                {
                    // supersampling for antialiasing
                    Vector3 col = new Vector3();
                    for (int s = 0; s < ns; s++)
                    {
                        float u = (float)(j + Utils.rnd.NextDouble()) / (float)nx;
                        float v = (float)(i + Utils.rnd.NextDouble()) / (float)ny;

                        Ray r = cam.getRay(u, v);
                        col += color(r, tree, 0);
                    }

                    col /= (float)ns;
                    // gamma correction
                    col = new Vector3((float)Math.Sqrt(col.x()),
                                      (float)Math.Sqrt(col.y()),
                                      (float)Math.Sqrt(col.z()));
                    // values written to file
                    int ir = (int)(255.99f * col.r());
                    int ig = (int)(255.99f * col.g());
                    int ib = (int)(255.99f * col.b());
                    Console.Write(ir + " " + ig + " " + ib + "\n");
                }
            }
        }
Пример #7
0
 public static Vector3 cross(Vector3 a, Vector3 b)
 {
     return(new Vector3(a.y() * b.z() - a.z() * b.y(),
                        -(a.x() * b.z() - a.z() * b.x()),
                        a.x() * b.y() - a.y() * b.x()));
 }
Пример #8
0
 // other operations
 public static float dot(Vector3 a, Vector3 b)
 {
     return(a.x() * b.x() + a.y() * b.y() + a.z() * b.z());
 }