【引入】
1. 目的:当我们观察空间任何一个不透明的物体时,只能看到该物体朝向我们的那些表面,其余的表面由于物体所遮挡我们看不到。所以需要消隐,来消除被遮挡的不可见的线或面,消除二义性,绘制出意义明确、富有真实感的立体图形。
2. 分类:
1)物体空间消隐算法:Roberts算法、光线透射法
2)图像空间消隐算法:Z缓冲区(Z-Buffer)算法、扫描线Z-buffer算法、区域子分割算法。
一、Z-Buffer消隐算法(深度缓冲器算法)
1. 原理:
1)该算法有帧缓冲器和深度缓冲器,对应两个数组:intensity(x, y)——属性数组(帧缓存器)存储图像空间每个可见像素的光强或颜色、depth(x, y)——深度数组(z-buffer)存放图像空间每个可见像素的z坐标。2)先将Z缓冲器中各单元的初始值置为最小值。当要改变某个像素的颜色值时,首先检查当前多边形的深度值是否大于该像素原来的深度值(保存在该像素所对应的Z缓冲器的单元中),如果大于原来的Z值,说明当前多边形更靠近观察点,用它的颜色替代像素原来的颜色。
2. 算法优缺点
1)算法简单直观,像素级上以近物替代远物,有利于硬件实现;
2)占用空间大,没有利用图形的相关性与连续性,像素级上的消隐算法;
3. 改进:只用一个深度缓存变量zb的改进算法;
3. 关键问题:点与多边形的包含性检测
1)射线法:由被测点P处向y = -∞方向作射线,交点个数是奇数,则被测点在多边形内部,否则在外部。
若射线正好经过多边形的顶点,则采用“左开右闭”的原则来实现,即:当射线与某条边的顶点相交时,若边在射线的左侧,交点有效,计数;若在射线的右侧,交点无效,不计数。
2)弧长法:以p点为圆心,作单位圆,把边投射到单位圆上,对应一段段弧长,规定逆时针为正,顺时针为负,计算弧长代数和。
代数和为0,点在多边形外部;代数和为2π,点在多边形内部;代数和为π,点在多边形边上。
3)以顶点符号为基础的弧长累加法:
p是被测点,按照弧长法,p点的代数和为2π。做一个规定来取代原来的弧长计算:
同一个象限认为是0,跨过一个象限是π/2,跨过两个象限是π。这样当腰计算代数和的时候,就不要去投影了,只要根据点所在的象限一下子就能判断出多少度。
二、区间扫描线消隐算法
1. 思想:扫描线的交点把这条扫描线分成了若干个区间,每个区间上必然是同样一种颜色。
对于有重合的区间,如a6a7这个区间,要么显示F2的颜色,要么显示F3的颜色,不会出现颜色的跳跃。那么如果把扫描线和多边形的这些交点求出来,对每个区间,只要判断一个像素的颜色,那么真个区间的颜色就都解决了。
2. 实现
投影多边形->求交点->交点排序
排序的结果就分成了一个个区间,然后在每个区间找当中一个像素(i, j),在(i, j)处计算每个相关面的z值,对相关深度值z进行比较,最大的那个表示可见。整个这段区间就画这个z值最大面的颜色。
其中小区间,要么取背景颜色,如a2a3、a4a5;要么在只有一个多边形情况下,取该多边形颜色,如a1a2。
三、区间子分割消隐算法(Warnock算法)
1. 思想:分而治之,利用了堆栈的数据结构。把物体投影到全屏幕窗口上,然后递归分割窗口,直到窗口内目标足够简单,可以显示为止。
2. 原理:
1)如果窗口内没有物体则按背景色显示;2)若窗口内只有一个面,则把该面显示出来;
3)否则,窗口内含有两个以上的面,则把窗口等分成四个子窗口。对于每个小窗口再做上述同样的处理。这样反复地进行下去。把四个窗口压在一个堆栈里(后进先出)。