天天看點

立方體畫家消隐算法與Z-Buffer消隐算法 比較

畫家算法,又稱深度排序法。

我們先看看它的算法:

(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-Buffer消隐算法 比較

二.立方體畫家消隐算法是對每個面求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;

}                         

立方體畫家消隐算法與Z-Buffer消隐算法 比較

繼續閱讀