Beispiel #1
0
        public override zwischenSpeicher scatter(ray r_in, hit_record rec, Vektor attenuation, ray scattered)
        {
            zwischenSpeicher zw = new zwischenSpeicher();

            attenuation = new Vektor(1, 1, 1);
            double refraction_ratio = rec.front_face ? (1 / ir) : ir;

            Vektor unit_direction = Vektor.unit_Vektor(r_in.Direction);
            double cos_theta      = Math.Min(Vektor.dot(unit_direction * -1, rec.normal), 1);
            double sin_theta      = Math.Sqrt(1 - cos_theta * cos_theta);

            bool   cannot_refract = refraction_ratio * sin_theta > 1;
            Vektor direction;

            if (cannot_refract)
            {
                direction = Vektor.reflect(unit_direction, rec.normal);
            }
            else
            {
                direction = Vektor.refract(unit_direction, rec.normal, refraction_ratio);
            }

            scattered = new ray(rec.p, direction);

            zw.attenuation = attenuation;
            zw.scattered   = scattered;
            zw.IsTrue      = true;

            return(zw);
        }
Beispiel #2
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));
            }
        }
Beispiel #3
0
        public static Vektor ray_color(ray r, hittable world, int depth)
        {
            hit_record rec = new hit_record();

            if (depth <= 0)
            {
                return(new Vektor(0, 0, 0));
            }

            zwischenSpeicher zw = world.Hit(r, 0.0001, Mathe.infinity, rec);

            if (zw.IsTrue)
            {
                rec = zw.rec;
                ray              scattered   = new ray();
                Vektor           attenuation = new Vektor();
                zwischenSpeicher zw1         = rec.mat_ptr.scatter(r, rec, attenuation, scattered);

                if (zw1.IsTrue)
                {
                    attenuation = zw1.attenuation;
                    scattered   = zw1.scattered;

                    return(attenuation * ray_color(scattered, world, depth - 1));
                }
                return(new Vektor(0, 0, 0));
            }

            Vektor unit_direction = Vektor.unit_Vektor(r.Direction);
            var    t   = 0.5 * (unit_direction.Y + 1);
            Vektor col = (1 - t) * new Vektor(1, 1, 1) + t * new Vektor(0.5, 0.7, 1);

            return(col);
        }
Beispiel #4
0
        public override bool hit(Ray r, float t_min, float t_max, ref hit_record rec)
        {
            Vector3 oc           = r.origin() - center(r._time);
            float   a            = Vector3.dot(r.direction(), r.direction());
            float   b            = 2.0f * Vector3.dot(oc, r.direction());
            float   c            = Vector3.dot(oc, oc) - radius * radius;
            float   discriminant = b * b - 4 * a * c;

            if (discriminant > 0)
            {
                // update the hit_record to pass the information back to the calling object
                float temp = (-b - (float)Math.Sqrt(b * b - 4 * a * c)) / (2 * a);                  // check the roots
                if (temp < t_max && temp > t_min)
                {
                    rec.t      = temp;
                    rec.p      = r.point(rec.t);
                    rec.normal = (rec.p - center(r._time)) / radius;
                    rec.mat    = material;
                    return(true);
                }

                temp = (-b + (float)Math.Sqrt(b * b - 4 * a * c)) / (2 * a);
                if (temp < t_max && temp > t_min)
                {
                    rec.t      = temp;
                    rec.p      = r.point(rec.t);
                    rec.normal = (rec.p - center(r._time)) / radius;
                    rec.mat    = material;
                    return(true);
                }
            }
            return(false);
        }
Beispiel #5
0
        public override bool scatter(Ray r_in, hit_record rec, ref Vector3 attenuation, ref Ray scattered)
        {
            Vector3 target = rec.normal + Utils.random_in_unit_sphere();

            scattered   = new Ray(rec.p, target);
            attenuation = abledo.value(0.0f, 0.0f, ref rec.p);
            return(true);
        }
Beispiel #6
0
        public override bool scatter(Ray r_in, hit_record rec, ref Vector3 attenuation, ref Ray scattered)
        {
            Vector3 reflected = Utils.reflect(r_in.direction().unit_vector(), rec.normal);

            scattered   = new Ray(rec.p, reflected + fuzz * Utils.random_in_unit_sphere());
            attenuation = abledo.value(0.0f, 0.0f, ref rec.p);
            return(Vector3.dot(scattered.direction(), rec.normal) > 0.0f);
        }
Beispiel #7
0
        public override bool scatter(Ray r_in, hit_record rec, ref Vector3 attenuation, ref Ray scattered)
        {
            Vector3 outward_norm;
            Vector3 reflected = Utils.reflect(r_in.direction(), rec.normal);
            float   ni_over_nt;

            attenuation = new Vector3(1.0f, 1.0f, 1.0f);
            Vector3 refracted    = new Vector3();
            float   reflect_prob = 0.0f;
            float   cosine       = 0.0f;

            if (Vector3.dot(r_in.direction(), rec.normal) > 0.0f)
            {
                outward_norm = -1.0f * rec.normal;
                ni_over_nt   = reflect_index;
                cosine       = reflect_index * Vector3.dot(r_in.direction(), rec.normal) / r_in.direction().length();
            }
            else
            {
                outward_norm = rec.normal;
                ni_over_nt   = 1.0f / reflect_index;
                cosine       = -1.0f * Vector3.dot(r_in.direction(), rec.normal) / r_in.direction().length();
            }

            // determine probability for reflecting vs refracting based on if a refraction is possible
            if (Utils.refract(r_in.direction(), outward_norm, ni_over_nt, ref refracted))
            {
                reflect_prob = Utils.schlick(cosine, reflect_index);
            }
            else
            {
                scattered    = new Ray(rec.p, reflected);
                reflect_prob = 1.0f;
            }

            // decide whether to reflect or refract
            if (Utils.rnd.NextDouble() < reflect_prob)
            {
                scattered = new Ray(rec.p, reflected);
            }
            else
            {
                scattered = new Ray(rec.p, refracted);
            }
            return(true);
        }
Beispiel #8
0
        public override bool hit(Ray r, float t_min, float t_max, ref hit_record rec)
        {
            hit_record temp_rec     = new hit_record();
            bool       hit_anything = false;
            float      closest      = t_max;

            for (int i = 0; i < hitables.Count; i++)
            {
                //cycle through all hitables and return the hit closest to the camera
                if (((Hitable)hitables [i]).hit(r, t_min, closest, ref temp_rec))
                {
                    hit_anything = true;
                    closest      = temp_rec.t;
                    rec          = temp_rec;
                }
            }

            return(hit_anything);
        }
Beispiel #9
0
        public override bool hit(Ray r, float t_min, float t_max, ref hit_record rec)
        {
            if (box.hit(r, t_min, t_max))
            {
                hit_record left_rec  = new hit_record();
                hit_record right_rec = new hit_record();
                bool       hit_left  = left.hit(r, t_min, t_max, ref left_rec);
                bool       hit_right = right.hit(r, t_min, t_max, ref right_rec);

                if (hit_left && hit_right)
                {
                    if (left_rec.t < right_rec.t)
                    {
                        rec = left_rec;
                    }
                    else
                    {
                        rec = right_rec;
                    }
                    return(true);
                }
                else if (hit_left)
                {
                    rec = left_rec;
                    return(true);
                }
                else if (hit_right)
                {
                    rec = right_rec;
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Beispiel #10
0
        public override zwischenSpeicher Hit(ray r, double t_min, double t_max, hit_record rec)
        {
            zwischenSpeicher zw = new zwischenSpeicher();
            Vektor           oc = r.Origin - center;
            var a      = r.Direction.length_squared();
            var half_b = Vektor.dot(oc, r.Direction);
            var c      = oc.length_squared() - radius * radius;

            var discriminant = half_b * half_b - a * c;

            if (discriminant < 0)
            {
                zw.IsTrue = false;
                return(zw);
            }
            var sqrtd = Math.Sqrt(discriminant);

            var root = (-half_b - sqrtd) / a;

            if (root < t_min || t_max < root)
            {
                root = (-half_b + sqrtd) / a;
                if (root < t_min || t_max < root)
                {
                    zw.IsTrue = false;
                    return(zw);
                }
            }

            rec.t = root;
            rec.p = r.at(rec.t);
            Vektor outward_normal = (rec.p - center) / radius;

            rec.set_face_normal(r, outward_normal);
            rec.mat_ptr = mat_ptr;

            zw.rec    = rec;
            zw.IsTrue = true;

            return(zw);
        }
Beispiel #11
0
        public override zwischenSpeicher Hit(ray r, double t_min, double t_max, hit_record rec)
        {
            zwischenSpeicher zw           = new zwischenSpeicher();
            hit_record       temp_rec     = new hit_record();
            bool             hit_anything = false;
            var closest_so_far            = t_max;

            foreach (var Object in objects)
            {
                zwischenSpeicher zw1 = Object.Hit(r, t_min, closest_so_far, temp_rec);
                if (zw1.IsTrue)
                {
                    temp_rec       = zw1.rec;
                    hit_anything   = true;
                    closest_so_far = temp_rec.t;
                    rec            = temp_rec;
                }
            }

            zw.rec    = rec;
            zw.IsTrue = hit_anything;

            return(zw);
        }
Beispiel #12
0
 public virtual bool scatter(Ray r_in, hit_record rec, ref Vector3 attenuation, ref Ray scattered)
 {
     return(false);
 }
Beispiel #13
0
 public virtual bool hit(Ray r, float t_min, float t_max, ref hit_record rec)
 {
     return(false);
 }