public override bool Hit(Ray r, double tMin, double tMax, ref HitRecord record)
        {
            var hitAnything  = false;
            var closestSoFar = tMax;

            foreach (var t in _hitables)
            {
                if (!t.Hit(r, tMin, closestSoFar, ref record))
                {
                    continue;
                }

                hitAnything  = true;
                closestSoFar = record.T;
            }

            return(hitAnything);
        }
예제 #2
0
        static Vec3 Color(Ray ray, HitableItems world, int depth)
        {
            var record = new HitRecord();

            // Ignore close hits as they're likely the cause of rounding errors
            // with t values. Not ignoring causes an undesirable visual effect
            // called the shadow acne.
            if (world.Hit(ray, 0.001, double.MaxValue, ref record))
            {
                return((depth < 50 && record.Material.Scatter(ray, record, out Vec3 attenuation, out Ray scatterRay))
                    ? attenuation * Color(scatterRay, world, depth + 1)
                    : ZeroVector);
            }

            var unitDirection = Vec3.UnitVector(ray.Direction);
            var t             = 0.5 * (unitDirection.Y + 1);

            return((1 - t) * UnitVector + t * Background);
        }
예제 #3
0
        public bool hit(Ray r, float t_min, float t_max, ref HitRecord rec)
        {
            HitRecord temp_rec       = new HitRecord();
            bool      hit_something  = false;
            float     closest_so_far = t_max;

            foreach (Hitable h in this.hitableList)
            {
                if (h == null)
                {
                    continue;
                }
                if (h.hit(r, t_min, closest_so_far, ref temp_rec))
                {
                    hit_something  = true;
                    closest_so_far = temp_rec.t;
                    rec            = temp_rec;
                }
            }
            return(hit_something);
        }
        public override bool Hit(Ray r, double tMin, double tMax, ref HitRecord record)
        {
            var oc           = r.Origin - _center;
            var a            = Vec3.Dot(r.Direction, r.Direction);
            var b            = Vec3.Dot(oc, r.Direction);
            var c            = Vec3.Dot(oc, oc) - _radius * _radius;
            var discriminant = b * b - a * c;

            if (discriminant > 0)
            {
                var sqrtDiscriminant = Math.Sqrt(discriminant);
                var solution1        = (-b - sqrtDiscriminant) / a;
                if (solution1 < tMax && solution1 > tMin)
                {
                    record.T = solution1;
                    record.PointOfIntersection = r.PointAtParameter(record.T);

                    // Normal is computed by computing the vector center to
                    // point of intersection Dividing by radius causes this
                    // vector to become a unit vector.
                    record.Normal   = (record.PointOfIntersection - _center) / _radius;
                    record.Material = _material;
                    return(true);
                }

                var solution2 = (-b + sqrtDiscriminant) / a;
                if (solution2 < tMax && solution2 > tMin)
                {
                    record.T = solution2;
                    record.PointOfIntersection = r.PointAtParameter(record.T);
                    record.Normal   = (record.PointOfIntersection - _center) / _radius;
                    record.Material = _material;
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        static private Vector3 ch8_color(Ray r, HitableList hitableList, int depth)
        {
            HitRecord rec = new HitRecord();

            if (hitableList.hit(r, 0.0001f, float.MaxValue, ref rec))
            {
                Ray     scattered   = null;
                Vector3 attenuation = null;
                if (depth > 0 && rec.mat.scatter(r, rec, ref attenuation, ref scattered))
                {
                    return(attenuation * ch8_color(scattered, hitableList, depth - 1));
                }
                else
                {
                    return(new Vector3(0, 0, 0));
                }
            }
            else
            {
                float t = 0.5f * (r.direction().normalized.y() + 1);
                return(new Vector3(1.0f, 1.0f, 1.0f) * (1 - t) + new Vector3(0.5f, 0.7f, 1.0f) * t);
            }
        }
예제 #6
0
        static Vec3 color(Ray r, IHitable world, int depth)
        {
            HitRecord rec = new HitRecord();

            if (world.hit(r, 0.001F, float.MaxValue, ref rec))
            {
                Ray  scattered   = new Ray();
                Vec3 attenuation = new Vec3();
                if (depth < 50 && rec.mat.scatter(r, rec, ref attenuation, ref scattered))
                {
                    return(attenuation * color(scattered, world, depth + 1));
                }
                else
                {
                    return(new Vec3(0, 0, 0));
                }
            }
            else
            {
                Vec3  unitDirection = Vec3.unitVector(r.direction());
                float t             = 0.5F * (unitDirection.y() + 1.0F);
                return((1.0F - t) * new Vec3(1.0F, 1.0F, 1.0F) + t * new Vec3(0.5F, 0.7F, 1.0F));
            }
        }
 public abstract bool Hit(Ray r, double tMin, double tMax, ref HitRecord record);
예제 #8
0
 public abstract bool Scatter(Ray incidentRay, HitRecord rec, out Vec3 attenuation, out Ray scatteredRay);