示例#1
0
        /// <summary>
        /// 利用层次包围盒计算颜色
        /// </summary>
        /// <param name="r"></param>
        /// <param name="world"></param>
        /// <param name="depth"></param>
        /// <returns></returns>
        public static SColor Color(Ray r, BVH_node world, int depth)
        {
            AABB aBB = new AABB();

            world.Bounding_box(0, 0, ref aBB);
            if (aBB.Hit(r, 1e-5))
            {
                ShadeRec rec = new ShadeRec();
                world.Hit(r, 1e-5, ref rec);
                if (rec.IsHit)
                {
                    Ray      scattered   = new Ray();
                    Vector3D attenuation = new Vector3D();
                    SColor   emitted     = rec.Material.Emitted(rec);//光颜色
                    if (depth < 1 && 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(1, 1, 1);//无背景色
                }
            }
            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(1, 0, 0);//无背景色
            }
        }
示例#2
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();
        }