Lesson 3 Hidden_faces_removal_z_buffer

  1. 画家算法:
    1. 画家算法问题:
  2. Z-buffer
  • Lesson2中的渲染结果在嘴巴处出现层叠问题,在这讲中通过z-buffer来进行解决

画家算法:

画家算法问题:

  • 在渲染三维物体时,三维模型在 z 轴上是连续的,三维模型间会互相组合交错,这种通过画家算法控制层级的方案很难奏效。
  • 下图中三个互相交错的三角形,无法区分层级

Z-buffer

  • z-buffer通过比较每个像素的深度信息来解决层级问题.

  • 对于每个三角形,遍历每一个像素,像素取最靠近相机的那个三角形像素的深度信息,最终渲染时我们按这个深度缓冲逐像素渲染三角形即可
// 首先假设深度默认值都是负无穷 -∞(这里可以是无穷大,也可以是无穷小,依坐标系而定)
for (each triangle T)              // 遍历每个三角形
   for (each sample (x,y,z) in T)  // 遍历三角形里的每个像素
        if (z > zbuffer[x,y])        // 如果深度大于已有的值,
            framebuffer[x,y] = rgb;  // 则更新颜色,
            zbuffer[x,y] = z;        // 并更新 zbuffer
        else
            // do nothing            // 小于已有的值,就说明这个像素点被遮挡不需要绘制了
  • 值得注意的一点是这里使用重心坐标跟上一节一样,对(x,y)进行插值.然后根据得到的(1-u-v,u,v)来计算深度值.
  • 相关代码
void triangle(Vec3f t0, Vec3f t1, Vec3f t2, TGAImage &image, TGAColor color,float* zbuffer) { 
    int minXVal = min(t0.x,min(t1.x,t2.x));
    int maxXVal = max(t0.x,max(t1.x,t2.x));
    int minYVal = min(t0.y,min(t1.y,t2.y));
    int maxYVal = max(t0.y,max(t1.y,t2.y));

    Vec3f pts[] = {t0,t1,t2};
    for(int i = minXVal; i <= maxXVal; ++i)
    {
        for(int j = minYVal; j <= maxYVal; ++j)
        {
            Vec3f u = barycentric(pts,Vec2i(i,j));
            if(u.x < 0.0 || u.y < 0.0 || u.z < 0.0)     continue;
            //根据重心坐标参数,计算当前三角形像素的深度.
            float depthZ = 0.0;
            depthZ += u.x*t0.z + u.y*t1.z + u.z*t2.z;
            if(depthZ > zbuffer[i*width+j])
            {
                zbuffer[i*width+j] = depthZ;
                image.set(i,j,color);
            }

        }
    }
}