public bool Scatter(Ray ray, HitRecord hitRecord, ref Vector3 attentuation, ref Ray scattered) { var scatterDir = hitRecord.Normal + MathExt.RandomUnitVector(); if (Vector3Ext.NearZero(scatterDir)) { scatterDir = hitRecord.Normal; } scattered = new Ray(hitRecord.Point, scatterDir, ray.Time); attentuation = Albedo; 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); }