예제 #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 BVH_Node(List <Hitable> l, float t0, float t1)
        {
            // randomly select an axis to sort child nodes by
            int axis = Utils.rnd.Next(3);

            if (axis == 0)
            {
                //x
                l.Sort(Utils.hitable_box_compare_x);
            }
            else if (axis == 1)
            {
                //y
                l.Sort(Utils.hitable_box_compare_y);
            }
            else
            {
                //z
                l.Sort(Utils.hitable_box_compare_z);
            }

            // build the tree
            if (l.Count == 1)
            {
                left  = l [0];
                right = l [0];
            }
            else if (l.Count == 2)
            {
                left  = l [0];
                right = l [1];
            }
            else
            {
                List <Hitable> l_hitables = l.GetRange(0, (int)Math.Floor(l.Count / 2.0f) + 1);
                List <Hitable> r_hitables = l.GetRange(l_hitables.Count, l.Count - l_hitables.Count);
                left  = new BVH_Node(l_hitables, t0, t1);
                right = new BVH_Node(r_hitables, t0, t1);
            }

            AABB box_left  = new AABB();
            AABB box_right = new AABB();

            // ensure that there is a possible bounding box before continuing
            if (!left.bounding_box(t0, t1, ref box_left) || !right.bounding_box(t0, t1, ref box_right))
            {
                Console.Error.WriteLine("No possible bounding box in BVH constructor!");
                List <Hitable> l_hitables = l.GetRange(0, (int)Math.Floor(l.Count / 2.0f) + 1);
                List <Hitable> r_hitables = l.GetRange(l_hitables.Count, l.Count - l_hitables.Count);
                Console.Error.WriteLine(l_hitables.Count + " " + r_hitables.Count);
            }
            box = AABB.surrounding_box(box_left, box_right);
        }
예제 #3
0
        // used for comparing bounding boxes of two hitables
        public static int hitable_box_compare_x(Hitable a, Hitable b)
        {
            AABB box_left  = new AABB();
            AABB box_right = new AABB();

            if (!a.bounding_box(0.0f, 0.0f, ref box_left) || !b.bounding_box(0.0f, 0.0f, ref box_right))
            {
                Console.Error.WriteLine("No possible bounding box during x comparison");
            }
            if (box_left.min().x() - box_right.min().x() < 0.0f)
            {
                return(-1);
            }
            else
            {
                return(1);
            }
        }
예제 #4
0
        private static Vec3 Color(Ray r, Hitable world, int depth)
        {
            HitRecord rec = new HitRecord();

            if (world.Hit(r, 0.001, double.MaxValue, out rec))
            {
                Ray  scattered   = new Ray();
                Vec3 attenuation = new Vec3();
                Vec3 emitted     = rec.Material.emitted(rec.U, rec.V, rec.P);

                if (depth < 50 && rec.Material.Scatter(r, rec, out attenuation, out scattered))
                {
                    return(emitted + attenuation * Color(scattered, world, depth + 1));
                }
                else
                {
                    return(emitted);
                }
            }
            else
            {
                return(new Vec3(0.0, 0.0, 0.0));
            }
        }