public static bool Dielectric(Ray r, HitRecord rec, ref float3 attenuation, ref Ray scattered, ref Random rand) { var refractionIndex = rec.material.refractionIndex; float3 outwardNormal; float3 reflected = RayMath.Reflect(r.direction, rec.normal); float niOverNt; attenuation = new float3(1f, 1f, 1f); float3 refracted; float cosine; if (math.dot(r.direction, rec.normal) > 0f) { outwardNormal = -rec.normal; niOverNt = refractionIndex; cosine = refractionIndex * math.dot(r.direction, rec.normal) / math.length(r.direction); } else { outwardNormal = rec.normal; niOverNt = 1f / refractionIndex; cosine = -math.dot(r.direction, rec.normal) / math.length(r.direction); } var reflectProbability = RayMath.Refract(r.direction, outwardNormal, niOverNt, out refracted) ? RayMath.Schlick(cosine, refractionIndex) : 1f; scattered = rand.NextFloat() < reflectProbability ? new Ray(rec.p, reflected) : new Ray(rec.p, refracted); return(true); }
public static bool Metal(Ray r, HitRecord rec, ref float3 attenuation, ref Ray scattered, ref Random random) { var m = rec.material; float3 reflected = RayMath.Reflect(math.normalize(r.direction), rec.normal); scattered = new Ray(rec.p, reflected + m.fuzziness * Utils.RandomInUnitSphere(random)); attenuation = m.albedo; return(math.dot(scattered.direction, rec.normal) > 0); }