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); }
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); }
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); }
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); } }
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);
public abstract bool Scatter(Ray incidentRay, HitRecord rec, out Vec3 attenuation, out Ray scatteredRay);