/// <summary> /// 直接计算颜色 /// </summary> /// <param name="r">射线</param> /// <param name="world">世界</param> /// <param name="depth">迭代次数</param> /// <returns></returns> public static SColor Color(Ray r, World world, int depth) { ShadeRec rec = world.Hit(r, 1e-5); if (rec.IsHit) { Ray scattered = new Ray(); Vector3D attenuation = new Vector3D(); SColor emitted = rec.Material.Emitted(rec);//光颜色 if (depth < 50 && rec.Material.Scatter(r, rec, ref attenuation, ref scattered)) { SColor colorTemp = Color(scattered, world, depth + 1); colorTemp = colorTemp * new SColor(attenuation); //有反射则将当前发光体发出的光和散射的颜色预以叠加 return(colorTemp + emitted); } else { //无反射则直接取发光射出的颜色 return(emitted); } } else { Vector3D unitDirection = Vector3D.UnitVector(r.Direction); double t = 0.5 * (unitDirection.Y + 1.0); return(new SColor((1.0 - t) + t * 0.5, (1.0 - t) + t * 0.7, (1.0 - t) + t * 1)); //return new SColor(0, 0, 0);//无背景色 } }
/// <summary> /// 渲染 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Btn_render_Click(object sender, EventArgs e) { //开始时间 DateTime startTime = DateTime.Now; //构建世界 World world = new World(); world.Bulid();//根据bulid构建 //world = World.RandomScene1();//随机构建函数1(封面图1) //world = World.RandomScene2();//随即构建函数2(封面图2) //根据world的物体构造层次包围盒树 BVH_node bVH = new BVH_node(world.GeometryObjects, world.GeometryObjects.Count, 0, 0); //画布参数 int nx = 200; //宽 int ny = 100; //高 Bitmap bitmap = new Bitmap(nx, ny); //画布 int ns = 10; //画布上一个像素点的实际随机采样数 //相机参数 Point3D lookfrom = new Point3D(1, 0.5f, 1.5f); Vector3D lookat = new Vector3D(0, 0, 0f); Camera cam = new Camera(lookfrom, lookat, new Vector3D(0, 1, 0), 60, (double)(nx) / (double)(ny), 0, (lookfrom - lookat).Length(), 0.0, 1.0); //Camera cam = new Camera();//默认相机参数,使用默认相机,则相机获取射线的函数一样要替换成默认 //遍历画布上的每一点,计算出该点的颜色并画到画布上 for (int i = 0; i < nx; i++) { for (int j = 0; j < ny; j++) { SColor col = new SColor(); //像素点颜色 for (int s = 0; s < ns; s++) //随机采样,消除锯齿 { //像素点的每一次采样具体计算 double u = (double)(i + RTUtils.rd.NextDouble()) / (double)nx; //该点在水平方向上的比例 double v = (double)(j + RTUtils.rd.NextDouble()) / (double)ny; //该点在垂直方向上的比例 Ray r = cam.GetRayWith_Time(u, v); //获取从相机到该点的射线(运动+景深) //Ray r = cam.GetRay(u, v);//获取从相机到该点的射线(默认) //Ray r = cam.GetRayWith_Time(u, v);//获取从相机到该点的射线(景深) SColor colTemp = RTUtils.Color(r, world, 0); //采样点颜色值 col = col + colTemp; //采样颜色总和 } //ns次采样的平均颜色 col = col / ns; col = new SColor(Math.Sqrt(col.R), Math.Sqrt(col.G), Math.Sqrt(col.B)); //对颜色进行伽马矫正 bitmap.SetPixel(i, ny - j - 1, col.GetColor255()); //画上该点颜色 //设置进度 int pro = (int)((((i + 1) * ny + j) * 100.0) / (nx * ny) + 1); SetPos(pro); } } string fileneame = "result" + DateTime.Now.Millisecond.ToString() + ".jpeg"; bitmap.Save(fileneame); //avi_bmps.Add(bitmap); pictureBox1.Image = bitmap; textBox1.Text = "渲染时间:" + (DateTime.Now - startTime).ToString(); }
public Constant_texture(SColor color) { Color = color; }