Z-Buffer 或 Depth-Buffer 方法
在查看包含非透明物体和表面的图片时,无法从更靠近眼睛的物体后面看到那些物体。要获得逼真的屏幕图像,必须去除这些隐藏的表面。这些表面的识别和去除被称为隐藏表面问题。
Z-buffer,也称为Depth-buffer法,是隐面检测常用的方法之一。它是一种图像空间方法。图像空间方法基于要在 2D 上绘制的像素。对于这些方法,运行时间复杂度是像素数乘以对象数。并且空间复杂度是像素数量的两倍,因为需要两个像素阵列,一个用于帧缓冲区,另一个用于深度缓冲区。
Z-buffer 方法比较投影平面上每个像素位置的表面深度。通常 z 轴表示为深度。 Z-buffer 方法的算法如下:
算法 :
First of all, initialize the depth of each pixel.
i.e, d(i, j) = infinite (max length)
Initialize the color value for each pixel
as c(i, j) = background color
for each polygon, do the following steps :
for (each pixel in polygon's projection)
{
find depth i.e, z of polygon
at (x, y) corresponding to pixel (i, j)
if (z < d(i, j))
{
d(i, j) = z;
c(i, j) = color;
}
}
让我们考虑一个例子来更好地理解算法。假设给定的多边形如下:
在开始时,假设每个像素的深度是无限的。
由于 z 值,即给定多边形中每个位置的深度值为 3,应用该算法,结果为:
现在,让我们更改 z 值。在下图中,z 值从 0 变为 3。
在开始时,每个像素的深度将是无限的:
现在,在像素上生成的 z 值将有所不同,如下所示:
因此,在 Z 缓冲方法中,每个表面在表面上一次处理一个位置。之后,比较深度值,即像素的 z 值,最接近的即(最小 z)表面确定要在帧缓冲区中显示的颜色。 z 值,即深度值通常被归一化到 [0, 1] 范围内。当 z = 0 时,它被称为Back Clipping Pane ,当 z = 1 时,它被称为Front Clipping Pane 。
在此方法中,使用了 2 个缓冲区:
- 帧缓冲区
- 深度缓冲区
深度计算:
众所周知,平面方程为:
ax + by + cz + d = 0, this implies
z = -(ax + by + d)/c, c!=0
每个深度的计算可能非常昂贵,但是通过使用如下图所示的增量方法,可以将计算减少到每个像素一次添加:
让我们将 A 点的深度表示为 Z,将 B 点的深度表示为 Z'。所以 :
AX + BY + CZ + D = 0 implies
Z = (-AX - BY - D)/C ------------(1)
Similarly, Z' = (-A(X + 1) - BY -D)/C ----------(2)
Hence from (1) and (2), we conclude :
Z' = Z - A/C ------------(3)
因此,深度的计算可以通过在(归一化)观察坐标系中记录每个多边形的平面方程,然后使用增量法求深度 Z 来完成。
因此,总而言之,可以说这种方法比较了投影平面上每个像素位置的表面深度。物体深度通常是从观察平面沿观察系统的 z 轴测量的。
例子 :
令 S1、S2、S3 为曲面。最靠近投影平面的表面称为可见表面。计算机将从表面 1 开始(任意)并将其值放入缓冲区。它会为下一个表面做同样的事情。然后它会检查每个重叠像素并检查哪个更接近观察者,然后显示适当的颜色。在视平面位置 (x, y),表面 S1 距视平面的深度最小,因此在该位置可见。
要记住的要点:
1) Z 缓冲区方法不需要对多边形进行预排序。
2)即使有很多多边形,这种方法也可以快速执行。
3)这可以在硬件中实现以克服速度问题。
4)不需要对象与对象的比较。
5)这种方法可以应用于非多边形对象。
6)该算法的硬件实现在一些图形工作站中是可用的。
7)该方法使用简单,不需要额外的数据结构。
8)多边形的z值可以增量计算。
9)不能应用于透明表面,即它只处理不透明表面。例如:
10)如果场景中只有几个对象要被渲染,那么这种方法就没有吸引力了,因为额外的缓冲区和更新缓冲区所涉及的开销。
11)绘制隐藏物品可能会浪费时间。