📜  Z-Buffer 或 Depth-Buffer 方法

📅  最后修改于: 2022-05-13 01:57:05.588000             🧑  作者: Mango

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 个缓冲区:

  1. 帧缓冲区
  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)绘制隐藏物品可能会浪费时间。