private static Vec3f Color(Ray r, HitableList world, int depth, Random drand) { HitRecord record = new HitRecord(); if (world.Hit(r, 0.0001f, float.MaxValue, ref record)) { Ray scattered = new Ray(); Vec3f attenuation = Vec3f.Zero; if (depth < 50 && record.Material.Scatter(r, record, out attenuation, out scattered, drand)) { return(attenuation * Color(scattered, world, depth + 1, drand)); } else { return(Vec3f.Zero); } } else { Vec3f unit_direction = r.Direction.GetNormal(); float t = 0.5f * (unit_direction.Y + 1.0f); return((1.0f - t) * Vec3f.One + t * (new Vec3f(0.5f, 0.7f, 1.0f))); } }
public static HitableList RandomScene(Random drand) { int n = 500; var world = new HitableList(); world.Add(new Sphere(new Vec3f(0, -1000f, 0), 1000, new Lambertian(new Vec3f(0.5f, 0.5f, 0.5f)))); int i = 1; for (int a = -11; a < 11; a++) { for (int b = -11; b < 11; b++) { float choose_mat = (float)drand.NextDouble(); var center = new Vec3f(a + 0.9f * (float)drand.NextDouble(), 0.2f, b + 0.9f * (float)drand.NextDouble()); if ((center - new Vec3f(4f, 0.2f, 0)).GetLength() > 0.9f) { if (choose_mat < 0.8f) // diffuse { world.Add(new Sphere(center, 0.2f, new Lambertian(new Vec3f((float)drand.NextDouble() * (float)drand.NextDouble(), (float)drand.NextDouble() * (float)drand.NextDouble(), (float)drand.NextDouble() * (float)drand.NextDouble())))); } else if (choose_mat < 0.95f) // metal { var o = new Vec3f( 0.5f * (1f + (float)drand.NextDouble()), 0.5f * (1f + (float)drand.NextDouble()), 0.5f * (1f + (float)drand.NextDouble()) ); world.Add(new Sphere(center, 0.2f, new Metal(o, 0.5f * (float)drand.NextDouble()))); } else // glass { world.Add(new Sphere(center, 0.2f, new Dielectric(1.5f))); } } } } world.Add(new Sphere(Vec3f.UnitY, 1.0f, new Dielectric(1.5f))); world.Add(new Sphere(new Vec3f(-4f, 1f, 0), 1.0f, new Lambertian(new Vec3f(0.4f, 0.2f, 0.1f)))); world.Add(new Sphere(new Vec3f(4f, 1f, 0), 1.0f, new Metal(new Vec3f(0.7f, 0.6f, 0.5f), 0.0f))); return(world); }