可见表面检测


当我们观看包含不透明物体和表面的图片时,我们无法从视野中看到距离眼睛较近的物体后面的那些物体。我们必须删除这些隐藏的表面才能获得逼真的屏幕图像。这些表面的识别和去除称为隐藏表面问题

有两种方法可以消除隐藏的表面问题 -对象空间方法图像空间方法。对象空间方法在物理坐标系中实现,图像空间方法在屏幕坐标系中实现。

当我们想要在 2D 屏幕上显示 3D 对象时,我们需要识别从所选观看位置可见的屏幕部分。

深度缓冲(Z 缓冲)方法

该方法由Cutmull 开发。这是一种图像空间方法。基本思想是测试每个表面的 Z 深度以确定最近的(可见)表面。

在此方法中,每个表面一次在整个表面上一次单独处理一个像素位置。比较像素的深度值,并且最接近(最小 z)表面确定要在帧缓冲区中显示的颜色。

它在多边形表面上的应用非常有效。表面可以按任何顺序进行处理。为了覆盖较远的多边形,使用两个名为帧缓冲区深度缓冲区的缓冲区。

深度缓冲区用于在处理表面时存储 (x, y) 位置的深度值 (0 ≤ 深度 ≤ 1)。

缓冲区用于存储每个位置(x,y)处颜色值的强度值。

z 坐标通常标准化为范围 [0, 1]。z 坐标的 0 值表示后剪切窗格,z 坐标的 1 值表示前剪切窗格。

Z缓冲法

算法

步骤 1 - 设置缓冲区值 -

深度缓冲区 (x, y) = 0

帧缓冲区 (x, y) = 背景颜色

Step-2 - 处理每个多边形(一次一个)

对于多边形的每个投影 (x, y) 像素位置,计算深度 z。

如果 Z > 深度缓冲区 (x, y)

计算表面颜色,

设置深度缓冲区(x,y)= z,

帧缓冲区 (x, y) = 表面颜色 (x, y)

优点

  • 它很容易实现。
  • 如果以硬件实现,它可以减少速度问题。
  • 它一次处理一个对象。

缺点

  • 它需要大内存。
  • 这是一个耗时的过程。

扫描线法

它是一种识别可见表面的图像空间方法。该方法仅具有单个扫描线的深度信息。为了需要一条扫描线的深度值,我们必须在处理下一条扫描线之前同时对与给定扫描线相交的所有多边形进行分组和处理。为此维护了两个重要的表:边表多边形表。

边表- 它包含场景中每条线的坐标端点、每条线的反斜率以及指向多边形表以将边连接到曲面的指针。

多边形表- 它包含平面系数、表面材料属性、其他表面数据,并且可能是指向边缘表的指针。

扫描线法

为了便于搜索穿过给定扫描线的表面,形成了边缘的活动列表。活动列表仅存储那些按 x 递增顺序穿过扫描线的边缘。还为每个表面设置一个标志,以指示沿扫描线的位置是在表面内部还是外部。

每条扫描线上的像素位置从左到右进行处理。在与曲面的左侧相交处,曲面标志打开,在右侧,该标志关闭。仅当多个表面在某个扫描线位置打开其标志时,才需要执行深度计算。

面积细分法

区域细分方法通过定位代表单个表面一部分的那些视图区域来发挥优势。将总观看区域分成越来越小的矩形,直到每个小区域都是单个可见表面的一部分或根本没有表面的投影。

继续此过程,直到可以轻松地将细分分析为属于单个表面,或者直到它们缩小到单个像素的大小。执行此操作的一个简单方法是在每个步骤中将区域连续划分为四个相等的部分。表面与指定区域边界可以具有四种可能的关系。

  • 周围表面- 完全包围该区域的表面。

  • 重叠表面- 部分位于区域内部、部分位于区域外部的表面。

  • 内表面- 完全位于该区域内的表面。

  • 外表面- 完全位于该区域之外的表面。

面积细分法

用于确定区域内表面能见度的测试可以用这四种分类来描述。如果满足以下条件之一,则不需要对指定区域进行进一步细分 -

  • 所有表面都是相对于该区域的外表面。
  • 该区域中只有一个内部、重叠或周围的表面。
  • 周围表面遮盖区域边界内的所有其他表面。

背面检测

用于识别多面体背面的快速且简单的对象空间方法基于“内-外”测试。点 (x, y, z) 位于具有平面参数 A、B、C 和 D 的多边形表面的“内部”,如果当内部点沿着表面的视线时,该多边形必须是背面(我们在这张脸的内部,从我们的观察位置看不到它的正面)。

我们可以通过考虑具有笛卡尔分量(A、B、C)的多边形表面的法向量N来简化此测试。

一般来说,如果 V 是从眼睛(或“相机”)位置观察方向的矢量,则该多边形是背面,如果

越南 > 0

此外,如果对象描述转换为投影坐标并且您的观看方向平行于观看 z 轴,则 -

V = (0, 0, V z ) V.N = V Z C

这样我们只需要考虑法向量N的分量 C 的符号。

在观察方向沿负 $Z_{V}$ 轴的右手观察系统中,如果 C < 0,则多边形是背面。此外,我们看不到法线具有 z 分量 C = 0 的任何面,因为您的观察方向朝向该多边形。因此,一般来说,如果任何多边形的法向量具有 z 分量值,我们就可以将其标记为背面 -

C <= 0

背面检测

类似的方法可以用在采用左手观察系统的封装中。在这些包中,平面参数 A、B、C 和 D 可以根据顺时针方向指定的多边形顶点坐标(与右手系统中使用的逆时针方向不同)计算。

此外,背面具有远离观看位置的法向向量,当观看方向沿正 $Z_{v}$ 轴时,由 C >= 0 标识。通过检查定义对象的不同平面的参数 C,我们可以立即识别所有背面。

背面

A缓冲法

A 缓冲区方法是深度缓冲区方法的扩展。A-buffer 方法是卢卡斯电影工作室为渲染系统 Renders Everything You Ever Saw (REYES) 开发的可见性检测方法。

A 缓冲区扩展了深度缓冲区方法以允许透明度。A缓冲区中的关键数据结构是累积缓冲区。

A缓冲法

A 缓冲区中的每个位置都有两个字段 -

  • 深度字段- 它存储正实数或负实数

  • 强度字段- 它存储表面强度信息或指针值

A 缓冲区字段

如果深度 >= 0,则该位置存储的数字是与相应像素区域重叠的单个表面的深度。然后,强度字段存储该点表面颜色的 RGB 分量以及像素覆盖百分比。

如果深度 < 0,则表示多个表面对像素强度的贡献。然后强度字段存储指向表面数据链接列表的指针。A 缓冲区中的表面缓冲区包括 -

  • RGB 强度分量
  • 不透明度参数
  • 深度
  • 面积覆盖百分比
  • 表面标识符

该算法的运行方式与深度缓冲区算法类似。深度和不透明度值用于确定像素的最终颜色。

深度排序法

深度排序方法同时使用图像空间和对象空间操作。深度排序方法执行两个基本功能 -

  • 首先,表面按深度递减的顺序排序。

  • 其次,从最大深度的表面开始,按顺序对表面进行扫描转换。

多边形表面的扫描转换是在图像空间中执行的。这种解决隐藏表面问题的方法通常称为画家算法。下图展示了深度排序的效果 -

深度排序法

该算法首先按深度排序。例如,多边形的初始“深度”估计可以被取为多边形的任何顶点的最接近的z值。

让我们采用列表末尾的多边形 P。考虑 z 范围与 P 重叠的所有多边形 Q。在绘制P之前,我们进行以下测试。如果以下任何一个测试是肯定的,那么我们可以假设 P 可以在 Q 之前绘制。

  • x 范围不重叠吗?
  • y 范围不重叠吗?
  • 从视点来看,P 是否完全位于 Q 平面的另一侧?
  • Q 与视点完全在 P 平面的同一侧吗?
  • 多边形的投影不重叠吗?

如果所有测试都失败,则我们使用 P 或 Q 的平面分割另一个。新切割的多边形将插入到深度顺序中,并且该过程将继续。理论上,这种划分可以生成 O(n 2 ) 个单独的多边形,但实际上,多边形的数量要少得多。

二元空间划分 (BSP) 树

二进制空间分区用于计算可见性。要构建 BSP 树,应该从多边形开始并标记所有边。一次仅处理一条边,延伸每条边,使其将平面一分为二。将树中的第一条边作为根。根据后续边是在内部还是在外部添加后续边。跨越树中已存在的边的延伸的边被分成两部分,并且都被添加到树中。

BSP 树
  • 由上图可知,首先取A为根。

  • 列出图(a)中的所有节点。

  • 将根A前面的所有节点放在节点A的左侧,将根A后面的所有节点放在右侧,如图(b)所示。

  • 首先处理所有前面的节点,然后处理后面的节点。

  • 如图(c)所示,我们首先处理节点B。由于节点B前面没有任何内容,因此我们输入了 NIL。然而,我们的节点C位于节点B的后面,因此节点C将位于节点B的右侧。

  • 对节点D重复相同的过程。