public bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered)
        {
            attenuation = Vector3.One;
            float etai_over_etat = (rec.Front_face) ? (1.0f / Ref_idx) : (Ref_idx);

            Vector3 unit_direction = Vector3.Normalize(r_in.Direction);
            float   cos_theta      = Math.Min(Vector3.Dot(-unit_direction, rec.Normal), 1.0f);
            float   sin_theta      = (float)Math.Sqrt(1.0f - cos_theta * cos_theta);

            if (etai_over_etat * sin_theta > 1.0f)
            {
                Vector3 reflected = Helpers.Reflect(unit_direction, rec.Normal);
                scattered = new Ray(rec.P, reflected);
                return(true);
            }
            float reflect_prob = Helpers.Schlick(cos_theta, etai_over_etat);

            if (Helpers.random.NextDouble() < reflect_prob)
            {
                Vector3 reflected = Helpers.Reflect(unit_direction, rec.Normal);
                scattered = new Ray(rec.P, reflected);
                return(true);
            }

            Vector3 refracted = Helpers.Refract(unit_direction, rec.Normal, etai_over_etat);

            scattered = new Ray(rec.P, refracted);
            return(true);
        }
Exemple #2
0
        static Vector3 Ray_color(Ray r, HitTable world, int depth)
        {
            Hit_Record rec = default;

            // If we've exceeded the ray bounce limit, no more light is gathered.
            if (depth <= 0)
            {
                return(Vector3.Zero);
            }

            if (world.Hit(r, 0.001f, Helpers.Infinity, ref rec))
            {
                Ray     scattered;
                Vector3 attenuation;
                if (rec.Mat_ptr.Scatter(r, rec, out attenuation, out scattered))
                {
                    return(attenuation * Ray_color(scattered, world, depth - 1));
                }
                return(Vector3.Zero);
            }

            Vector3 unit_direction = Vector3.Normalize(r.Direction);
            var     t = 0.5f * (unit_direction.Y + 1.0f);

            return((1.0f - t) * new Vector3(1.0f, 1.0f, 1.0f) + t * new Vector3(0.5f, 0.7f, 1.0f));
        }
        public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec)
        {
            Vector3 oc           = r.Origin - this.Center;
            float   a            = r.Direction.LengthSquared();
            float   half_b       = Vector3.Dot(oc, r.Direction);
            float   c            = oc.LengthSquared() - this.Radius * this.Radius;
            float   discriminant = half_b * half_b - a * c;

            if (discriminant > 0)
            {
                float root = (float)Math.Sqrt(discriminant);
                float temp = (-half_b - root) / a;
                if (temp < t_max && temp > t_min)
                {
                    rec.T = temp;
                    rec.P = r.At(rec.T);
                    Vector3 outward_normal = (rec.P - this.Center) / this.Radius;
                    rec.Set_Face_Normal(r, outward_normal);
                    rec.Mat_ptr = Material;
                    return(true);
                }
                temp = (-half_b + root) / a;
                if (temp < t_max && temp > t_min)
                {
                    rec.T = temp;
                    rec.P = r.At(rec.T);
                    Vector3 outward_normal = (rec.P - this.Center) / this.Radius;
                    rec.Set_Face_Normal(r, outward_normal);
                    rec.Mat_ptr = Material;
                    return(true);
                }
            }

            return(false);
        }
Exemple #4
0
        public bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered)
        {
            Vector3 scatter_direction = rec.Normal + Helpers.Random_unit_Vector();

            scattered   = new Ray(rec.P, scatter_direction);
            attenuation = this.Albedo;
            return(true);
        }
        public bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered)
        {
            Vector3 unit_vector = Vector3.Normalize(r_in.Direction);
            Vector3 reflected   = Helpers.Reflect(unit_vector, rec.Normal);

            scattered = new Ray(rec.P, reflected + fuzz * Helpers.Random_in_unit_sphere());

            attenuation = this.Albedo;
            return(Vector3.Dot(scattered.Direction, rec.Normal) > 0);
        }
        public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec)
        {
            Hit_Record temp_rec       = default;
            bool       hit_anything   = false;
            float      closest_so_far = t_max;

            foreach (var o in this.Objects)
            {
                if (o.Hit(r, t_min, closest_so_far, ref temp_rec))
                {
                    hit_anything   = true;
                    closest_so_far = temp_rec.T;
                    rec            = temp_rec;
                }
            }

            return(hit_anything);
        }