コード例 #1
0
        public bool Hit(Ray r, float t0, float t1, ref Hit_Record rec)
        {
            var t = (k - r.Origin.X) / r.Direction.X;

            if (t < t0 || t > t1)
            {
                return(false);
            }
            var y = r.Origin.Y + t * r.Direction.Y;
            var z = r.Origin.Z + t * r.Direction.Z;

            if (y < y0 || y > y1 || z < z0 || z > z1)
            {
                return(false);
            }
            rec.U = (y - y0) / (y1 - y0);
            rec.V = (z - z0) / (z1 - z0);
            rec.T = t;
            var outward_normal = new Vector3(1, 0, 0);

            rec.Set_Face_Normal(r, outward_normal);
            rec.Mat_ptr = mp;
            rec.P       = r.At(t);
            return(true);
        }
コード例 #2
0
        public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec)
        {
            var origin    = r.Origin;
            var direction = r.Direction;

            origin.X = cos_theta * r.Origin.X - sin_theta * r.Origin.Z;
            origin.Z = sin_theta * r.Origin.X + cos_theta * r.Origin.Z;

            direction.X = cos_theta * r.Direction.X - sin_theta * r.Direction.Z;
            direction.Z = sin_theta * r.Direction.X + cos_theta * r.Direction.Z;

            Ray rotated_r = new Ray(origin, direction, r.Time);

            if (!ptr.Hit(rotated_r, t_min, t_max, ref rec))
            {
                return(false);
            }

            var p      = rec.P;
            var normal = rec.Normal;

            p.X = cos_theta * rec.P.X + sin_theta * rec.P.Z;
            p.Z = -sin_theta * rec.P.X + cos_theta * rec.P.Z;

            normal.X = cos_theta * rec.Normal.X + sin_theta * rec.Normal.Z;
            normal.Z = -sin_theta * rec.Normal.X + cos_theta * rec.Normal.Z;

            rec.P = p;
            rec.Set_Face_Normal(rotated_r, normal);

            return(true);
        }
コード例 #3
0
        public bool Hit(Ray r, float t0, float t1, ref Hit_Record rec)
        {
            var t = (k - r.Origin.Y) / r.Direction.Y;

            if (t < t0 || t > t1)
            {
                return(false);
            }
            var x = r.Origin.X + t * r.Direction.X;
            var z = r.Origin.Z + t * r.Direction.Z;

            if (x < x0 || x > x1 || z < z0 || z > z1)
            {
                return(false);
            }
            rec.U = (x - x0) / (x1 - x0);
            rec.V = (z - z0) / (z1 - z0);
            rec.T = t;
            var outward_normal = new Vector3(0, 1, 0);

            rec.Set_Face_Normal(r, outward_normal);
            rec.Mat_ptr = mp;
            rec.P       = r.At(t);
            return(true);
        }
コード例 #4
0
        static Vector3 Ray_color(Ray r, Vector3 background, 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 the ray hits nothing, return the background color.
            if (!world.Hit(r, 0.001f, Helpers.Infinity, ref rec))
            {
                return(background);
            }

            Ray     scattered;
            Vector3 attenuation;
            Vector3 emitted = rec.Mat_ptr.Emitted(rec.U, rec.V, rec.P);

            if (!rec.Mat_ptr.Scatter(r, rec, out attenuation, out scattered))
            {
                return(emitted);
            }

            return(emitted + attenuation * Ray_color(scattered, background, world, depth - 1));
        }
コード例 #5
0
        public override 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);
        }
コード例 #6
0
        public override 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, r_in.Time);
            attenuation = this.Albedo.Value(rec.U, rec.V, rec.P);
            return(true);
        }
コード例 #7
0
        public override 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);
        }
コード例 #8
0
        public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec)
        {
            if (!this.box.Hit(r, t_min, t_max))
            {
                return(false);
            }

            bool hit_left  = left.Hit(r, t_min, t_max, ref rec);
            bool hit_right = right.Hit(r, t_min, hit_left ? rec.T : t_max, ref rec);

            return(hit_left || hit_right);
        }
コード例 #9
0
        public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec)
        {
            Ray moved_r = new Ray(r.Origin - offset, r.Direction, r.Time);

            if (!ptr.Hit(moved_r, t_min, t_max, ref rec))
            {
                return(false);
            }

            rec.P += offset;
            rec.Set_Face_Normal(moved_r, rec.Normal);

            return(true);
        }
コード例 #10
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);
        }
コード例 #11
0
        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;
                    this.Get_sphere_uv((rec.P - this.Center) / this.Radius, out rec.U, out rec.V);
                    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;
                    this.Get_sphere_uv((rec.P - this.Center) / this.Radius, out rec.U, out rec.V);
                    return(true);
                }
            }

            return(false);
        }
コード例 #12
0
        public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec)
        {
            Vector3 oc     = r.Origin - this.Center(r.Time);
            var     a      = r.Direction.LengthSquared();
            var     half_b = Vector3.Dot(oc, r.Direction);
            var     c      = oc.LengthSquared() - radius * radius;

            var discriminant = half_b * half_b - a * c;

            if (discriminant > 0)
            {
                var root = (float)Math.Sqrt(discriminant);

                var temp = (-half_b - root) / a;
                if (temp < t_max && temp > t_min)
                {
                    rec.T = temp;
                    rec.P = r.At(rec.T);
                    var outward_normal = (rec.P - this.Center(r.Time)) / radius;
                    rec.Set_Face_Normal(r, outward_normal);
                    rec.Mat_ptr = mat_ptr;
                    return(true);
                }

                temp = (-half_b + root) / a;
                if (temp < t_max && temp > t_min)
                {
                    rec.T = temp;
                    rec.P = r.At(rec.T);
                    var outward_normal = (rec.P - this.Center(r.Time)) / radius;
                    rec.Set_Face_Normal(r, outward_normal);
                    rec.Mat_ptr = mat_ptr;
                    return(true);
                }
            }
            return(false);
        }
コード例 #13
0
ファイル: Box.cs プロジェクト: akavasis/RaytracingTheNextWeek
 public bool Hit(Ray r, float t0, float t1, ref Hit_Record rec)
 {
     return(sides.Hit(r, t0, t1, ref rec));
 }
コード例 #14
0
 public override bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered)
 {
     attenuation = default;
     scattered   = null;
     return(false);
 }
コード例 #15
0
 public abstract bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered);
コード例 #16
0
 public override bool Scatter(Ray r_in, Hit_Record rec, out Vector3 attenuation, out Ray scattered)
 {
     scattered   = new Ray(rec.P, Helpers.Random_in_unit_sphere(), r_in.Time);
     attenuation = albedo.Value(rec.U, rec.V, rec.P);
     return(true);
 }
コード例 #17
0
        public bool Hit(Ray r, float t_min, float t_max, ref Hit_Record rec)
        {
            // Print occasional samples when debugging. To enable, set enableDebug true.
            const bool enableDebug = false;
            bool       debugging   = enableDebug && ((float)Helpers.random.NextDouble() < 0.00001f);

            Hit_Record rec1, rec2;

            rec1 = rec2 = default;

            if (!boundary.Hit(r, -Helpers.Infinity, Helpers.Infinity, ref rec1))
            {
                return(false);
            }

            if (!boundary.Hit(r, rec1.T + 0.0001f, Helpers.Infinity, ref rec2))
            {
                return(false);
            }

            if (debugging)
            {
                Console.WriteLine($"t0={rec1.T}, t1={rec2.T}");
            }

            if (rec1.T < t_min)
            {
                rec1.T = t_min;
            }
            if (rec2.T > t_max)
            {
                rec2.T = t_max;
            }

            if (rec1.T >= rec2.T)
            {
                return(false);
            }

            if (rec1.T < 0)
            {
                rec1.T = 0;
            }

            float ray_length = r.Direction.Length();
            float distance_inside_boundary = (rec2.T - rec1.T) * ray_length;
            float hit_distance             = neg_inv_density * (float)Math.Log(Helpers.random.NextDouble());

            if (hit_distance > distance_inside_boundary)
            {
                return(false);
            }

            rec.T = rec1.T + hit_distance / ray_length;
            rec.P = r.At(rec.T);

            if (debugging)
            {
                Console.WriteLine($"hit_distance = {hit_distance} \n " +
                                  $"rec.t = {rec.T} \n" +
                                  $"rec.p = {rec.P}");
            }

            rec.Normal     = new Vector3(1, 0, 0); // arbitrary
            rec.Front_face = true;                 // also arbitrary
            rec.Mat_ptr    = phase_function;

            return(true);
        }