计算机图形学消隐算法

9.1 常见消隐算法
消隐算法按其实现方式可分为图像空间消隐算法和景物空间消隐算法两大类。图像空间(屏幕坐标系)消隐算法以屏幕像素为采样单位,确定投影于每一像素的可见景物表面区域,并将其颜色作为该像素的显示颜色。景物空间消隐算法直接在景物空间(观察坐标系)中确定视点不可见的表面区域,并将它们表达成同原表面一致的数据结构。图像空间消隐算法有深度缓存器算法、A缓存器算法、区间扫描线算法等;景物空间消隐算法则包含BSP算法、多边形区域排序算法等;介于二者之间的有深度排序算法、区域细分算法、光线投射算法等。



深度缓存器算法



深度缓存器算法最早由Catmull提出,是一种典型的,也是最简单的图像空间面消隐算法,但其所需的存储容量较大,不仅要有帧缓存器来存放每个像素的颜色值,还需要有深度缓存器来存放画面上每一像素对应的可见表面采样点的深度值。由于通常选择z轴的负向为观察方向,因此算法沿着观察系统的z轴来计算各景物距离观察平面的深度,故该算法也称为Z-buffer算法。

Z-buffer算法的原理是:先将待处理的景物表面上的采样点变换到图像空间(屏幕坐标系),计算其深度值,并根据采样点在屏幕上的投影位置,将其深度值与已存贮在Z缓存器中相应像素处的原可见点的深度值进行比较。如果新的采样点的深度(z值)大于原可见点的深度,表明新的采样点遮住了原可见点,则用该采样点处的颜色值更新帧缓存器中相应像素的颜色值,同时用其深度值更新Z缓存器中的深度值;否则,不做更改。

深度缓存器算法最大的优点是算法原理简单,不过算法的复杂度为O(N),N为物体表面采样点的数目。另一优点是便于硬件实现。现在许多中高档的图形工作站上都配置有硬件实现的Z-buffer算法,以便于图形的快速生成和实时显示。

深度缓存器算法的缺点是占用太多的存储单元,假定屏幕分辨率为1024×768,则需要2×1024×768个存储单元,即使每一存储单元只占一个字节,也需要超过100万个字节。不过,若采用扫描线Z-buffer算法时,可以每次只对一条扫描线进行处理,这样深度缓存器所需的存储量仅为1×屏幕水平显示分辨率×深度存储位数,当然需要增加边表和多边形表的存储量。

深度缓存器算法的其它缺点还有它在实现反走样、透明和半透明等效果方面的困难。同时,在处理透明或半透明效果时,深度缓存器算法在每个像素点处只能找到一个可见面,即它无法处理多个多边形的累计颜色值。

区间扫描线算法



每一条扫描线被物体中多边形的边界在屏

幕的投影分割成若干相互邻接的子区间,每一子区间上只有一个可见面,如图9-3。因此,只要在每一个子区间内任一点处,在投影于该处的各多边形中找出在该处深度(z值)最大的多边形(最近的多边形),则这一多边形为该扫描线子区间内的唯一可见面,可按这一多边形的光照属性和几何位置计算确定子区间内各像素的显示颜色。这就是所谓的区间扫描线算法。区间扫描线算法也是一种图像空间消隐算法。


图9-1 区间扫描线算法原理

算法首先为各多边形建立一张边表和一张多边形表。边表需包含的内容有:进行消隐的场景中所有线段的端点坐标、线段斜率的倒数、指向多边形表中对应多边形的指针。多边形表需包含的内容有:各多边形的平面方程系数、各多边形的颜色值、指向边表的指针。在消隐算法执行的过程中,从边表和多边形表中提取信息,构造一张有效边表。有效边表中包含与当前扫描线相交的边,按x的升序进行排列。排列后这些边将扫描线分成一个个的子区间[xi, xi+1],如图9-2,可将扫描线上的子区间分为三种类型:


图9-2 扫描线子区间

(1)子区间为空,如图9-2中的子区间1和5。
(2)子区间中只包含一个多边形,如图9-2(a)中的2和4,图9-2(b) 中的2和4,图9-2(c) 中的4。
(3)子区间中包含多个多边形,如图9-2(a)中的3,图9-2(b) 中的3,图9-2(c)中的2和3。
若这些多边形在子区间内不相互贯穿,如图9-2(a)中的3,则仅需计算这些多边形在子区间任一端点处的深度,深度(z值)大的平面为可见面。若两多边形交于子区间一端点但不贯穿,如图9-2(b) 中的3,则只要计算它们在区间另一端点处的深度,深度大者为可见面。为了使算法能处理互相贯穿的多边形,如图9-2(c),扫描线上的分割点不仅应包含各多边形的边与扫描线的交点,而且应包含这些贯穿边界与扫描线的交点,如图9-2(c)中增加了一个分割点,从而形成了子区间2和3,否则算法不能处理多边形相互贯穿的情形。

当然还有另外一种难以处理的情形就是循环遮挡(实际上贯穿也可看作循环遮挡的一种),若存在这种情况,则需将多边形进行划分以消除循环遮挡。

在形成了子区间后,只要取其投影覆盖该子区间的各多边形,计算它们在区间端点处采样点的z值(深度),深度最大的平面为可见面。于是,需要在有效边表的每个分割点对应的数据结点中增加一类信息:为每个多边形建立一个标志位,以表示扫描线上每一子区间所对应的覆盖多边形。



深度排序算法



排序算法(Depth-Sorting Method)是介于图像空间消隐算法和景物空间消

隐算法之间的一种算法,它在景物空间中预先计算物体上各多边形可见性的优先级,然后再在图像空间中产生消隐图。深度排序算法可分为两步进行:
(1)将多边形按深度进行排序:距视点近的优先级高,距视点远的优先级低。
(2)由优先级低的多边形开始,逐个对多边形进行扫描转换。
其中步骤(1)是关键。

假定沿z轴的负向进行观察,因而z值大的距观察者近,多边形A上各点z坐标的最小值和最大值分别记作zmin(A)、zmax(A)。将多边形按深度进行排序的算法步骤为:
(1)对场景中的所有多边形按zmin(多边形)由小到大的顺序存入一个先进先出队列中,记为M,同时初始化一空的先进先出队列N(N中存放已确定优先级的多边形,优先级低的先进,扫描转换时也先处理)。
(2)若M中的多边形个数为1,则将M中的多边形直接加入到N中,算法结束;否则按先进先出的原则从M中取出第一个多边形A进行处理(A是M中zmin值最小的多边形),同时将A从M中删除。
(3)从当前M中任意选择一多边形B,对A与B进行判别。
①若对M中任意的B均有zmin(B)>zmax(A),则说明A是M中所有多边形中深度最深的,它与其它多边形在深度方向上无任何重叠,不会遮挡别的多边形。将A按先进先出原则加入N中,转(2);否则继续。
②否则说明存在某一多边形B,A与B有深度重叠,则需要依次进行以下判别:
a. 判别多边形A和B在xoy平面上投影的包围盒有无重叠,若无重叠,则A、B在队列中的顺序无关紧要,将A按先进先出原则加入N中,转(2);否则继续。
b. 判别平面A是否完全位于B上A与B的重叠平面之后,若是,将A按先进先出原则加入N中,转(2);否则继续。
c. 判别B上平面A与B的重叠平面是否完全位于A之前,若是,将A按先进先出原则加入N中,转(2);否则继续。
d. 判别多边形A和B在xoy平面上的投影有无重叠,若无重叠,则A、B在队列中的顺序无关紧要,将A按先进先出原则加入N中,转(2);否则在A与B投影的重叠区域中任取一点,分别计算出A、B在该点处的z值,若A的z值小,说明A距视点远,优先级低,将A按先进先出原则加入N中,转(2);若A的z值大,则交换A和B的关系,即将B看作是当前处理对象,转(3)进行M中其它多边形的判别。

排序完成后得到队列N,由于N是按优先级由低到高顺序排列的多边形先进先出队列,因此只需从N中逐个取出多边形进行扫描转换即可。



区域细分算法



区域细分算法的出发点是投影平面上一块足够小的区域可以被至多一个多边形所覆盖。因此,可以这样来构造算法:考察投影平

面上的一块区域,如果可以很“容易”地判断覆盖该区域中的哪个或哪些多边形是可见的,则可按这些多边形的光照属性和几何位置计算确定子区域内各像素的显示颜色;否则就将这块区域细分为若干较小的区域,并把上述推断原则递归地应用到每个较小的区域中去。当区域变得越来越小时,每块区域上所覆盖的多边形就越来越少,最终的区域会易于分析判断。这显然是图像空间消隐算法的一种,它利用了区域相关性。

在循环细分过程的每一阶段,可将每个多边形根据其投影与所考察的区域之间的关系分为4类:
(1)围绕多边形:多边形的投影完全包含了考察的那块区域;
(2)相交多边形:多边形的投影与该区域相交;
(3)被包含多边形:多边形的投影完全落在该区域之中;
(4)分离多边形:多边形的投影完全落在该区域之外。

根据这4种类别可以进行多边形的可见性测试。若以下条件之一为真,则可不必再对区域进一步加以细分而直接处理:
(1)所有多边形均是该区域的分离多边形,于是可直接将该区域中的所有像素点置为背景颜色。
(2)针对该区域,仅存在一个相交多边形,或仅存在一个被包含多边形,或仅存在一个围绕多边形。则可先将该区域中的所有像素点置为背景颜色,再将相应多边形的颜色值填入对应像素点的帧缓存中。
(3)针对该区域,有多于一个的相交多边形、被包含多边形或围绕多边形,则计算所有围绕的、相交的、以及被包含的多边形在该区域4个顶点处的z坐标,如果存在一个围绕多边性,它的4个z坐标比其它任何多边性的z坐标都大(最靠近视点),那么,可将该区域中的所有像素点置为该多边形的颜色值。
区域细分方式有两种,一种是将区域简单地分割为四块大小相等的矩形;另一种是自适应细分,即沿多边形的边界对区域进行细分,这样可以减少分割次数,但在区域细分和测试多边形与区域的关系方面处理更为复杂。



光线投射算法



光线投射算法是建立在几何光学基础上的一种算法,它模拟人的视觉效果,沿视线的路径跟踪场景的可见面。其基本思想是:由视点出发通过投影窗口(屏幕)的任一像素位置构造一条射线(投影线),将射线与场景中的所有多边形求交,如果有交点,就将该像素点的颜色置为深度(z值)最大的交点(最近的交点)所属的多边形的颜色;如果没有交点,就将该像素点的颜色置为背景颜色。算法步骤可简单描述如下:
(1)通过视点和投影平面(显示屏幕)上的所有像素点作一入射线,形成投影线。
(2)将任

一投影线与场景中的所有多边形求交。
(3)若有交点,则将所有交点按z值的大小进行排序,取出最近交点所属多边形的颜色;若没有交点,则取出背景的颜色。



BSP树



BSP树与画家算法类似,BSP算法也是从远到近往屏幕上覆盖景物的画面,BSP算法在对场景进行消隐之前需建立场景的BSP树。

实际上,建立场景BSP树的过程是对场景所含景物多边形递归地进行二叉分类的过程。先在场景中选取任意一剖分平面P将场景的整个空间分割成两个子空间(相对于视点,这两个子空间一个位于P之前,一个位于P之后)。相应地,场景中的景物也被P分成两组。由于C与P相交,因此P把C分割成两个物体C和D。这样,用剖面P进行第一次分割后,形成两组景物B、D和A、C(B、D在P之前,A、C在P之后)。然后再用剖分平面Q对第一次剖分生成的两个子空间进行分割,并对每一子空间中所含的景物进行分类,分为D和B,C和A(D、C在Q之前,B、A在Q之后)。

递归进行上述空间剖分和景物分类过程,直至每一子空间中所含景物少于给定的阈值为止,可表示成一棵BSP树,图9-14(b)示出了图9-14(a)的分割过程和形成的分类景物。对于由多边形组成的场景,常选择与某一多边形重合的平面作为分割平面。一旦构造完BSP树,即可依据当前视点所在的位置,对场景中每一分割平面所生成的两个子空间进行分类,其中包含视点的子空间标记为“front”,位于分割平面另一侧的子空间标记为“back”。然后,递归搜索场景的BSP树,优先绘制标识为“back”的子空间中所含景物。

BSP算法非常适合在场景不变视点变化的场合对场景中各多边形作快速排序,是一种决定场景可见性的有效方法。目前已有许多系统借助硬件来完成BSP树的生成和处理。



多边形区域排序算法



多边形区域排序算法是一种景物空间消隐算法。算法思想源于对隐藏面的观察:由于隐藏面是场景中位于场景可见面之后的多边形表面或表面的一部分,它们在投影面上的投影区域完全为可见面的投影所覆盖,因此,可以将多边形按深度值由小到大排序,是完全不可见的。

设场景内有n+1个多边形,且假定沿z轴的负向进行观察,记zmin(P)为多边形P上各顶点z坐标的的最小值。另外设定三个集合M、N和L,集合M存放待处理的多边形,集合N存放可见的多边形,集合L中存放排好序的多边形。多边形区域排序算法可简单描述如下:
(1)初始化:将场景中的多边形全部放入集合M中,集合N、L置为空。
(2)若集合M中的多边形的个数为1,则从集合M中取出该多边形放入N中,转(6)。否则

对M中的所有多边形按zmin(P)由大到小(由近到远)的顺序进行预排序,放入L中。
(3)从L中取出当前深度(z值)最大的多边形,即最近的多边形作为裁剪多边形PA,求出该多边形在xoy面上的投影多边形A。且从集合M和L中去掉PA。
(4)若L为空,则将PA放入N中(可见面),转(2)。否则,从L中取出一个多边形PB,并从集合L中去掉PB,用A对PB的投影B进行裁剪,得到Bin。
(5)若Bin为空,即没有重叠部分,转(4);否则求出重叠多边形PAin和PBin各自顶点的z值,据此比较其深度,以确定PA是否是离视点较近的多边形。若是,将多边形PB从M中去掉,将PBout加入到M中,转(4);否则,将多边形PAout放入M中,L置空,转(2)。
(6)扫描转换集合N中的多边形。

多边形区域排序算法可适用于任意多边形构成场景的消隐处理,比如它可以正确消隐循环遮挡的情况。


相关文档
最新文档