现在的位置: 首页 > 综合 > 正文

立方体画家消隐算法与Z-Buffer消隐算法 比较

2013年09月03日 ⁄ 综合 ⁄ 共 2794字 ⁄ 字号 评论关闭

画家算法,又称深度排序法。
我们先看看它的算法:
(1)将屏幕设成背景色,

(2)把要画的物体(多边形)按其离开视点的从远到近排序(#add 确定可以排序么?不会有交叉的面?这个距离又是指哪个点到哪个点? 从后文得知,画家算法不适用于交叉的情况,只能针对包围体,此距离也是个最小距离)。由此构成深度优先级表。然后从远到近画物体(多边形),近的就因为优先级高而覆盖远的多边形。由此可消隐。

z缓冲区算法(Z-buffer算法)
先开一个帧缓冲区记录每个像素的亮度值,再开一个Z缓冲区存放每个像素的深度值。那么对于每个像素而言,它有两个参数值,需要定义两个数组。所以,对于每一个像素,由于有了深度这个数组,它在内存中就是立体的了,所以,在内存中整个图像都是立体的。
然后,逐行扫描,就可以测出每一行的深度值了。以此达到消隐的作用。
由此,我们可以看到画家算法和Z-buffer算法1的不同之处。

应该说,它们之间最本质的区别在于:画家算法是按照物体(多边形)的深度进行排序,比较容易实现;而Z-buffer算法是按照图像每一个像素进行排序,比总体排序灵活简单。

立方体画家消隐算法与Z-Buffer消隐算法在别的方面有所类似,在<计算机图形学实践教程VC++ 孔令德>中,两个算法用到的立方体都是正交投影,而不是透视投影,即立方体远离视点时显示的立方体仍然是原大小,不变化.只是二种算法核心思想不同:

 

一.立方体Z-Buffer消隐是对于某一个像素点,不必对在靠近或远离视点的面进行排序,只需在遍历各面后找出该像素的深度最大的点(Z最大,即离视点最近)(先找深度大的点setPixel(),如果以后还有深度更大的,则通过设置新的颜色setPixel()来覆盖以前的点,其中要注意以yi为扫描线时,扫描线可能不与屏幕平行,可能是倾斜着的,就像把opengl的X轴绕Y轴旋转一个角度,如向量(1,-1,0),此次每次随x增大,z也会相应变化-A/C,其中(A,B,C)为该面的法向量),可以说它是对逐个像素进行深度判断进行的.主要代码如下:

for(T1=HeadE;T1!=NULL;T1=T1->next)//填充扫描线和多边形相交的区间

              {

                     if(In==false)

                     {

                            xb=T1->x;

                            CurDeep=-(xb*A+CurrentB->ScanLine*B+D)/C;//z=-(Ax+By+D)/C

                            In=true;//每访问一个结点,把In值取反一次

                     }

                     else//如果In值为真,则填充从当前结点的x值开始到下一结点的x值结束的区间

                     {

                            xe=T1->x;

                            for(double x=xb;x<=xe;x++)

                            {                                

                                   if(CurDeep>=ZB[ROUND(x)+200][CurrentB->ScanLine+200])//如果新的采样点的深度大于原采样点的深度,因为绘制每个面都会调用该函数,故以后的面中如果有更深度更大的点,则会覆盖以前的点的颜色.注意,此处要遍历[xb,xe]上的每个整数点,绘制连续的像素点,以连成一条线                            .

{

                                          ZB[ROUND(x)+200][CurrentB->ScanLine+200]=CurDeep;//xy坐标与数组下标保持一致,加200

                                          mdc->SetPixel(ROUND(x),CurrentB->ScanLine,RGB[Face]);

                                   }

                                   CurDeep+=DeepStep;                               

                            }

                            In=false;

                     }           

              }    

 

 

 

二.立方体画家消隐算法是对每个面求Z最小的值MinDeep,然后对这6个面按MinDeep值从小到大进行排序(即离视点近的面后画,来覆盖离视点远的面),然后再按从远到近画六个面即可.不过这种算法还是有局限的,它只是针对包围体(如立方体)来说的,如果对于那种不闭合的体(如2个相交且无限延伸的平面(就像opengl坐标系上的平面XOY和平面YOZ)),则会出现问题. 主要代码如下:

for(T1=HeadE;T1!=NULL;T1=T1->next)

       {         

              xb=T1->x;            CurDeep=-(xb*A+CurrentB->ScanLine*B+D)/C;//z=-(Ax+By-D)/C                               

              if(CurDeep<=F[Face].MinDeep)// 找一个面上深度最小(即Z最小,最远离视点)的点,此处不像Z-Buffer那样每次找2个点xb,xe,且需要遍历其中的每个x点,它只需找到最小值,而这个最小值必定在线段的2个端点上(要么是xb,要么是xe),故可以一个端点一个端点地访问找出Z的最小值即可,而且它暂时不绘制像素点,而是在最后把6个面按先远后近的顺序进行排序后再绘制这6个面.

              {

                  F[Face].MinDeep=CurDeep;//同上一行记录

              }

              CurDeep+=DeepStep;

}                         

 

抱歉!评论已关闭.