public bool Hit(Ray ray, float tMin, float tMax, ref HitRecord hitRecord) { var tempHitRecord = new HitRecord(); bool hitAnything = false; float closestSoFar = tMax; foreach (var hitable in _hitables) { if (hitable.Hit(ray, tMin, closestSoFar, ref tempHitRecord)) { hitAnything = true; closestSoFar = tempHitRecord.T; hitRecord = tempHitRecord; } } return(hitAnything); }
// Checks for collisions with all hittable objects public bool Hit(Ray r, double tMin, double tMax, HitRecord record) { HitRecord tempRecord = new HitRecord(); bool hitAnything = false; double closestSoFar = tMax; foreach (Hittable hittable in HittableObjects) { if (hittable.Hit(r, tMin, closestSoFar, tempRecord)) { hitAnything = true; closestSoFar = tempRecord.T; record.Set(tempRecord); } } return(hitAnything); }
public bool Hit(Ray ray, float tMin, float tMax, ref HitRecord hitRecord) { var currentCenter = Center(ray.Time); Vector3 oc = ray.Origin - currentCenter; var a = ray.Direction.LengthSquared(); var halfB = Vector3.Dot(oc, ray.Direction); var c = oc.LengthSquared() - Radius * Radius; float discriminant = halfB * halfB - a * c; if (discriminant < 0.0f) { return(false); } // Find the nearest root that lies in the acceptable range. float sqrtD = MathF.Sqrt(discriminant); float root = (-halfB - sqrtD) / a; if (root < tMin || root > tMax) { root = (-halfB + sqrtD) / a; if (root < tMin || root > tMax) { return(false); } } hitRecord.T = root; hitRecord.Point = ray.At(hitRecord.T); var outwardNormal = (hitRecord.Point - currentCenter) / Radius; hitRecord.SetFaceNormal(ray, outwardNormal); hitRecord.Material = _material; return(true); }
public bool Hit(Ray r, double tMin, double tMax, HitRecord record) { Vector3 oc = r.Origin - Center; double a = r.Direction.LengthSquared(); double halfB = oc.Dot(r.Direction); double c = oc.LengthSquared() - Radius * Radius; double discriminant = halfB * halfB - a * c; if (discriminant < 0) { return(false); } double sqrtDiscriminant = Math.Sqrt(discriminant); // Find the nearest root that lies in the acceptable range double root = (-halfB - sqrtDiscriminant) / a; if (root < tMin || tMax < root) { root = (-halfB + sqrtDiscriminant) / a; if (root < tMin || tMax < root) { return(false); } } record.T = root; record.Point = r.At(record.T); record.Normal = (record.Point - Center) / Radius; Vector3 outwardNormal = (record.Point - Center) / Radius; record.SetFaceNormal(r, outwardNormal); record.Material = Material; return(true); }
public bool Scatter(Ray rIn, HitRecord record, Vector3 attenuation, Ray scattered, Random rand) { attenuation.Set(new Vector3(1.0, 1.0, 1.0)); double refractionRatio = record.FrontFace ? (1.0 / RefractionIndex) : RefractionIndex; Vector3 unitDirection = rIn.Direction.Normalize(); double cosTheta = Math.Min(record.Normal.Dot(-unitDirection), 1.0); double sinTheta = Math.Sqrt(1.0 - cosTheta * cosTheta); bool cannotRefract = refractionRatio * sinTheta > 1.0; Vector3 direction; if (cannotRefract || reflectance(cosTheta, refractionRatio) > rand.NextDouble()) { direction = Vector3.Reflect(unitDirection, record.Normal); } else { direction = Vector3.Refract(unitDirection, record.Normal, refractionRatio); } scattered.Set(new Ray(record.Point, direction)); return(true); }
public bool Scatter(Ray ray, HitRecord hitRecord, ref Vector3 attentuation, ref Ray scattered) { attentuation = Vector3.One; float refractionRatio = hitRecord.FrontFace ? (1.0f / RefactionIndex) : RefactionIndex; var unitDir = Vector3.Normalize(ray.Direction); float cosTheta = Math.Min(Vector3.Dot(-unitDir, hitRecord.Normal), 1.0f); float sinTheta = MathF.Sqrt(1.0f - cosTheta * cosTheta); bool cannotRefract = refractionRatio * sinTheta > 1.0f; Vector3 direction; if (cannotRefract || Reflectance(cosTheta, refractionRatio) > MathExt.RandomFloat()) { direction = Vector3.Reflect(unitDir, hitRecord.Normal); } else { direction = Vector3Ext.Refract(unitDir, hitRecord.Normal, refractionRatio); } scattered = new Ray(hitRecord.Point, direction, ray.Time); return(true); }
private Vec3 Color(Ray ray, Hitable world, int depth, Random random) { var record = new HitRecord(); if (world.Hit(ray, this.tMin, this.tMax, ref record)) { Ray scatteredRay = null; Vec3 attenuation = null; if (depth < this.maxBounceDepth && record.Material.Scatter(ray, record, ref attenuation, ref scatteredRay, random)) { return(attenuation * Color(scatteredRay, this.world, depth + 1, random)); } else { return(this.black); } } else { var unitDirection = ray.Direction.Normalized; float t = 0.5f * (unitDirection.Y + 1); return(Vec3.Lerp(t, white, lightBlue)); } }