private Vector3 albedo;//漫反射系数 public override bool Scatter(Ray rIn, HitRecord rec, ref Vector3 attenuation, ref Ray scattered) { Vector3 target = rec.P + rec.Normal + RTUtils.RandomInUnitSphere(); scattered = new Ray(new Point3D(rec.P.X, rec.P.Y, rec.P.Z), target - rec.P); attenuation = albedo; return(true); }
private void button1_Click(object sender, EventArgs e) { int nx = 1080; int ny = 1080; int ns = 10; bmp = new Bitmap(nx, ny); Random rd = new Random(); List <Hitable> list = new List <Hitable>(); list.Add(new Sphere(new Point3D(0, 0, -1), 0.5, new Lambertian(new Vector3(0.8, 0.3, 0.3)))); list.Add(new Sphere(new Point3D(0, -100.5, -1), 100, new Lambertian(new Vector3(0.8, 0.8, 0.0)))); list.Add(new Sphere(new Point3D(1, 0, -1), 0.5, new Metal(new Vector3(0.8, 0.6, 0.2), 0.3))); list.Add(new Sphere(new Point3D(-1, 0, -1), 0.5, new Dielectrics(1.5))); HitableList world = new HitableList(list, 4); Camera cam = new Camera(new Point3D(-2, 2, 1), new Point3D(0, 0, -1), new Vector3(0, 1, 0), 90, (double)(nx) / (double)(ny)); for (int i = 0; i < nx; i++) { for (int j = 0; j < ny; j++) { Color3D col = new Color3D(); for (int s = 0; s < ns; s++) { double u = (double)(i + rd.NextDouble()) / (double)nx; double v = (double)(j + rd.NextDouble()) / (double)ny; Ray r = cam.GetRay(u, v); Color3D colTemp = RTUtils.Color(r, world, 0); col.R += colTemp.R; col.G += colTemp.G; col.B += colTemp.B; } col.R /= ns; col.G /= ns; col.B /= ns; col = new Color3D(Math.Sqrt(col.R), Math.Sqrt(col.G), Math.Sqrt(col.B)); int ir = (int)(255.99 * col.R); int ig = (int)(255.99 * col.G); int ib = (int)(255.99 * col.B); bmp.SetPixel(i, ny - j - 1, Color.FromArgb(ir, ig, ib)); } } pictureBox1.BackgroundImage = bmp; }
public override bool Scatter(Ray rIn, HitRecord rec, ref Vector3 attenuation, ref Ray scattered) { Vector3 outwardNormal = new Vector3(); Vector3 reflected = RTUtils.Reflect(rIn.Direction, rec.Normal); double niOverNt; attenuation = new Vector3(1, 1, 1); //衰减率 Vector3 refracted = new Vector3(); double reflect_prob; double cosine; if (Vector3.DotProduct(rIn.Direction, rec.Normal) > 0) { outwardNormal = rec.Normal * -1; niOverNt = refIdx; cosine = refIdx * Vector3.DotProduct(rIn.Direction, rec.Normal) / rIn.Direction.Length(); } else { outwardNormal = rec.Normal; niOverNt = 1.0 / refIdx; cosine = -Vector3.DotProduct(rIn.Direction, rec.Normal) / rIn.Direction.Length(); } if (RTUtils.Refract(rIn.Direction, outwardNormal, niOverNt, ref refracted)) { reflect_prob = RTUtils.Schlick(cosine, refIdx); } else { scattered = new Ray(new Point3D(rec.P.X, rec.P.Y, rec.P.Z), reflected); reflect_prob = 1.0; } if (RTUtils.rd.NextDouble() < reflect_prob) { scattered = new Ray(new Point3D(rec.P.X, rec.P.Y, rec.P.Z), reflected); } else { scattered = new Ray(new Point3D(rec.P.X, rec.P.Y, rec.P.Z), refracted); } return(true); }