Lesson 3 Hidden_faces_removal_z_buffer
Created At :
- 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);
}
}
}
}