public static Vector3 RandomInUnitSphere(this ImSoRandom random) { var p = new Vector3(); do { p = 2.0f * new Vector3(random.NextFloat(), random.NextFloat(), random.NextFloat()) - new Vector3(1, 1, 1); } while (p.LengthSquared() >= 1.0f); return(p); }
public static Vector3 RandomInUnitDisk(this ImSoRandom random) { var p = new Vector3(); do { p = 2.0f * new Vector3(random.NextFloat(), random.NextFloat(), 0) - new Vector3(1, 1, 0); } while (Vector3.Dot(p, p) >= 1.0f); return(p); }
public static (List <IHitable>, Camera) RandomScene(ImSoRandom rnd, int nx, int ny) { var world = new List <IHitable>(); var texture = new CheckerTexture(new ConstantTexture(0.2f, 0.3f, 0.1f), new ConstantTexture(0.9f, 0.9f, 0.9f)); world.Add(new Sphere(new Vector3(0, -1000f, 0), 1000, new Lambertian(texture))); for (int a = -11; a < 11; a++) { for (int b = -11; b < 11; b++) { float choose_mat = rnd.NextFloat(); var center = new Vector3(a + 0.9f * rnd.NextFloat(), 0.2f, b + 0.9f * rnd.NextFloat()); if ((center - new Vector3(4, 0.2f, 0)).Length() > 0.9) { if (choose_mat < 0.8) { // diffuse world.Add(new MovingSphere(center, center + new Vector3(0, 0.5f * rnd.NextFloat(), 0), 0.0f, 1.0f, 0.2f, new Lambertian(new ConstantTexture(rnd.NextFloat() * rnd.NextFloat(), rnd.NextFloat() * rnd.NextFloat(), rnd.NextFloat() * rnd.NextFloat())))); //world.Add(new Sphere(center, 0.2f, new Lambertian(new Vector3(rnd.NextFloat() * rnd.NextFloat(), rnd.NextFloat() * rnd.NextFloat(), rnd.NextFloat() * rnd.NextFloat())))); } else if (choose_mat < 0.95) { // metal world.Add(new Sphere(center, 0.2f, new Metal(new Vector3(0.5f * (1 + rnd.NextFloat()), 0.5f * (1 + rnd.NextFloat()), 0.5f * (1 + rnd.NextFloat())), 0.5f * rnd.NextFloat()))); } else { // glass world.Add(new Sphere(center, 0.2f, new Dialectric(1.5f))); } } } } world.Add(new Sphere(new Vector3(0, 1, 0), 1.0f, new Dialectric(1.5f))); world.Add(new Sphere(new Vector3(-4, 1, 0), 1.0f, new Lambertian(new ConstantTexture(0.4f, 0.2f, 0.1f)))); world.Add(new Sphere(new Vector3(4, 1, 0), 1.0f, new Metal(new Vector3(0.7f, 0.6f, 0.5f), 0f))); world.Add(new Sphere(new Vector3(0, 0, 0), 20.0f, new DiffuseLight(new ConstantTexture(new Vector3(1, 1, 1))))); var lookFrom = new Vector3(13, 2, 3); var lookAt = new Vector3(0, 0, 0); var distToFocus = 10; var aperture = 0.1f; var cam = new Camera(lookFrom, lookAt, new Vector3(0, 1, 0), 20, (float)nx / (float)ny, aperture, distToFocus, 0.0f, 1.0f); return(world, cam); }
public Ray GetRay(float u, float v, ImSoRandom rnd) { var rd = LensRadius * rnd.RandomInUnitDisk(); var offset = U * rd.X + V * rd.Y; float time = Time0 + rnd.NextFloat() * (Time1 - Time0); return(new Ray(Origin + offset, LowerLeftCorner + u * Horizontal + v * Vertical - Origin - offset, time)); }
public static (List <IHitable>, Camera) PoolScene(ImSoRandom rnd, int nx, int ny) { var world = new List <IHitable>(); world.Add(new Sphere(new Vector3(0, -1000f, 0), 1000, new Lambertian(new ConstantTexture(0.33f, 0.67f, 0.0f)))); var red = new ConstantTexture(0.68f, 0.13f, 0.16f); var yellow = new ConstantTexture(1f, 0.74f, 0.13f); var black = new ConstantTexture(0.14f, 0.07f, 0.07f); var white = new ConstantTexture(1f, 1f, 0.9f); for (var a = 1f; a <= 5; a += 1f) { var counter = 0 - a; for (var b = 0f; b < a; b += 1f) { var center = new Vector3(a * 0.9f - 5f, 0.5f, a / 2f - b - 0.5f); var colour = counter % 2 == 0 ? red : yellow; if (a == 3 && b == 1) { colour = black; } if (a == 3 && b == 2) { colour = red; } if (a == 5 && b == 4) { colour = red; } world.Add(new Sphere(center, 0.45f, new Lambertian(colour))); world.Add(new Sphere(center, 0.5f, new Dialectric(1.5f))); counter++; } } var cueCenter = new Vector3(-6, 0.5f, 0); var cueCenter1 = cueCenter + new Vector3(0.75f * rnd.NextFloat(), 0, 0); world.Add(new MovingSphere(cueCenter, cueCenter1, 0.0f, 1.0f, 0.5f, new Dialectric(1.5f))); world.Add(new MovingSphere(cueCenter, cueCenter1, 0.0f, 1.0f, 0.45f, new Lambertian(white))); world.Add(new RectXZ(-3, 3, -2, 2, 5, new DiffuseLight(new ConstantTexture(new Vector3(15, 15, 15))))); var lookFrom = new Vector3(-9, 3.5f, 12); var lookAt = new Vector3(-3, 0, 0); var distToFocus = (lookFrom - new Vector3(-6, 0.5f, 0)).Length(); var aperture = 0.5f; var cam = new Camera(lookFrom, lookAt, new Vector3(0, 1, 0), 20, (float)nx / (float)ny, aperture, distToFocus, 0.0f, 1.0f); return(world, cam); }
private static void RenderRow(Image <Rgba32> image, IHitable[] wl, Camera cam, int j, int nx, int ny, int ns, ImSoRandom rnd, ConcurrentDictionary <int, int> processedRows, ref uint rayCount) { var index = ny - 1 - j; var rowSpan = image.GetPixelRowSpan(index); for (int i = 0; i < nx; i++) { var col = new Vector3(0); for (var s = 0; s < ns; s++) { float u = ((float)i + rnd.NextFloat()) / (float)nx; float v = ((float)j + rnd.NextFloat()) / (float)ny; var r = cam.GetRay(u, v, rnd); col += Color(r, wl, 0, rnd, ref rayCount); } col /= (float)ns; col = new Vector3((float)Math.Sqrt(col.X), (float)Math.Sqrt(col.Y), (float)Math.Sqrt(col.Z)); rowSpan[i] = new Rgba32(col); } processedRows.TryAdd(j, Thread.CurrentThread.ManagedThreadId); }
public override bool Scatter(Ray rayIn, HitRecord rec, out Vector3 attenuation, out Ray scattererd, ImSoRandom random) { Vector3 reflected = Vector3.Reflect(rayIn.Direction, rec.Normal); attenuation = new Vector3(1.0f); Vector3 outward_normal; float niOverNt; float cosine; if (Vector3.Dot(rayIn.Direction, rec.Normal) > 0) { outward_normal = -rec.Normal; niOverNt = _refIndex; cosine = _refIndex * Vector3.Dot(rayIn.Direction, rec.Normal) / rayIn.Direction.Length(); } else { outward_normal = rec.Normal; niOverNt = 1.0f / _refIndex; cosine = -Vector3.Dot(rayIn.Direction, rec.Normal) / rayIn.Direction.Length(); } Vector3 refracted; float reflectProb; if (Refract(rayIn.Direction, outward_normal, niOverNt, out refracted)) { reflectProb = Schlick(cosine, _refIndex); } else { reflectProb = 1.0f; } if (random.NextFloat() < reflectProb) { scattererd = new Ray(rec.P, reflected, rayIn.Time); } else { scattererd = new Ray(rec.P, refracted, rayIn.Time); } return(true); }
public static Vector3 RandomVector(this ImSoRandom random) { return(new Vector3(10 + random.NextFloat() * 400f, 10 + random.NextFloat() * 400f, 10 + random.NextFloat() * 400f)); }