public override bool Hit(Ray r, float tMin, float tMax, ref HitRecord record) { Vec3f oc = r.Origin - Center; float a = Vec3f.Dot(r.Direction, r.Direction); float b = Vec3f.Dot(oc, r.Direction); float c = Vec3f.Dot(oc, oc) - Radius * Radius; float discriminant = b * b - a * c; if (discriminant > 0) { float tempSqrt = MathF.Sqrt(b * b - a * c); float temp = (-b - tempSqrt) / a; if (temp < tMax && temp > tMin) { record.t = temp; record.Point = r.PointAtParameter(record.t); record.Normal = (record.Point - Center) / Radius; record.Material = this.Material; return(true); } temp = (-b + tempSqrt) / a; if (temp < tMax && temp > tMin) { record.t = temp; record.Point = r.PointAtParameter(record.t); record.Normal = (record.Point - Center) / Radius; record.Material = this.Material; return(true); } } return(false); }
public abstract bool Scatter(Ray r, HitRecord rec, out Vec3f attenuation, out Ray Scattered, Random drand);
public static RayImage RenderParallelFor(int width, int height, int samples) { // creating image and storage. var img = new RayImage(); img.Width = width; img.Height = height; img.Pixels = new Rgb3f[width * height]; // setting up camera: var lookFrom = new Vec3f(5f, 5f, 5f); var lookAt = new Vec3f(0, 0, -1f); float dist_to_focus = (lookFrom - lookAt).GetLength(); float aperture = 2.0f; var cam = new Camera(lookFrom, lookAt, Vec3f.UnitY, 40, (float)width / (float)height, aperture, dist_to_focus); var wrand = new Random(); var world = RandomScene(wrand); // creating world. //var world = new HitableList( // new Sphere(new Vec3f(0f, 0f, -1f), 0.5f, new Lambertian(new Vec3f(0.1f, 0.2f, 0.5f))), // new Sphere(new Vec3f(0, -100.5f, -1f), 100, new Lambertian(new Vec3f(0.8f, 0.8f, 0.0f))), // new Sphere(new Vec3f(1f, 0f, -1f), 0.5f, new Metal(new Vec3f(0.8f, 0.6f, 0.2f), 0.0f)), // new Sphere(new Vec3f(-1f, 0f, -1f), 0.5f, new Dielectric(1.5f)), // new Sphere(new Vec3f(-1f, 0f, -1f), -0.45f, new Dielectric(1.5f)) // ); // looping height lines. Parallel.For(0, height - 1, (cur) => { var j = height - cur - 1; // invert it? int curLine = cur * width; var drand = new Random(); // create unique random object for each thread to prevent locking. for (int i = 0; i < width; i++) { Vec3f col = Vec3f.Zero; for (int s = 0; s < samples; s++) { float u = (float)(i + drand.NextDouble()) / (float)width; float v = (float)(j + drand.NextDouble()) / (float)height; Ray r = cam.GetRay(u, v, drand); //Vec3f p = r.PointAtParameter(2.0f); // still not used. col += Color(r, world, 0, drand); } col /= (float)samples; col = new Vec3f(MathF.Sqrt(col.X), MathF.Sqrt(col.Y), MathF.Sqrt(col.Z)); img.Pixels[curLine + i] = (Rgb3f)col; //img.Pixels[curLine + i] = new Rgb3f(0.3f, 0.4f, 0.6f); } //System.Threading.Thread.Sleep(5); }); return(img); }
public Ray(Vec3f o, Vec3f d) { this.Origin = o; this.Direction = d; }
public Metal(Vec3f a, float fuzz) { this.Albedo = a; this.Fuzz = fuzz < 1 ? fuzz : 1.0f; }
public Sphere(Vec3f center, float r, MaterialBase m) { this.Center = center; this.Radius = r; this.Material = m; }
public Lambertian(Vec3f a) { this.Albedo = a; }
public static Vec3f Reflect(Vec3f v, Vec3f n) { return(v - 2 * Dot(v, n) * n); }
public static float Dot(Vec3f l, Vec3f r) { return(l.X * r.X + l.Y * r.Y + l.Z * r.Z); }
public Vec3f Cross(Vec3f v) { return(Cross(this, v)); }
public float Dot(Vec3f v) { return(Dot(this, v)); }