1、Z緩沖區(Z-Buffer)算法
1973年,猶他大學學生艾德·卡姆爾(Edwin Catmull)獨 立開發出了能跟蹤屏幕上每個像素深度的算法 Z-buffer
Z-buffer讓計算機生成復雜圖形成為可能。Ed Catmull目 前擔任迪士尼動畫和皮克斯動畫工作室的總裁
Z緩沖器算法也叫深度緩沖器算法,屬於圖像空間消隱算法
該算法有幀緩沖器和深度緩沖器。對應兩個數組:
intensity(x,y)——屬性數組(幀緩沖器)
存儲圖像空間每個可見像素的光強或顏色
depth(x,y)——深度數組(z-buffer)
存放圖像空間每個可見像素的z坐標
假定xoy面為投影面,z軸為 觀察方向
過屏幕上任意像素點(x,y) 作平行於z軸的射線R,與物 體表面相交於p1和p 2 點
p1和p 2點的z值稱為該點的深 度值
z-buffer算法比較p1和p 2的z值, 將最大的z值存入z緩沖器中
顯然,p1在p 2前面,屏幕上(x,y) 這一點將顯示p1點的顏色
算法思想:先將Z緩沖器中各單元的初始值置為最小值。
當 要改變某個像素的顏色值時,首先檢查當前多邊形的深度值是否大於該像素原來的深度值(保存在該像素所對應的Z 緩沖器的單元中)
如果大於原來的z值,說明當前多邊形更靠近觀察點,用它的顏色替換像素原來的顏色
Z-Buffer算法() { 幀緩存全置為背景色 深度緩存全置為最小z值 for(每一個多邊形) { 掃描轉換該多邊形 for(該多邊形所覆蓋的每個象素(x,y) ) { 計算該多邊形在該象素的深度值Z(x,y); if(z(x,y)大於z緩存在(x,y)的值) { 把z(x,y)存入z緩存中(x,y)處 把多邊形在(x,y)處的顏色值存入幀緩存的(x,y)處 } } } }
z-Buffer算法的優點:
(1)Z-Buffer算法比較簡單,也很直觀
(2)在象素級上以近物取代遠物。與物體在屏幕上的出現 順序是無關緊要的,有利於硬件實現
z-Buffer算法的缺點:
(1)占用空間大
(2)沒有利用圖形的相關性與連續性,這是z-buffer算法 的嚴重缺陷
(3)更為嚴重的是,該算法是在像素級上的消隱算法
2、只用一個深度緩存變量zb的改進算法
一般認為,z-Buffer算法需要開一個與圖象大小相等的緩 存數組ZB,實際上,可以改進算法,只用一個深度緩存變 量zb
z-Buffer算法() { 幀緩存全置為背景色 for(屏幕上的每個象素(i,j)) { 深度緩存變量zb置最小值MinValue for(多面體上的每個多邊形Pk) { if(象素點(i,j)在pk的投影多邊形之內) { 計算Pk在(i,j)處的深度值depth; if(depth大於zb) { zb = depth; indexp = k;(記錄多邊形的序號) } } } If(zb != MinValue) 計算多邊形Pindexp在交點 (I,j) 處的光照 顏色並顯示 } }
關鍵問題:判斷象素點(i,j)是否在pk的投影多邊形之內, 不是一件容易的事。節省了空間但犧牲了時間。
計算機的很多問題就是在時間和空間上找平衡
另一個問題計算多邊形Pk在點(i,j)處的深度。設多邊 形Pk的平面方程為:
點與多邊形的包含性檢測:
(1)射線法
由被測點P處向 y = -∞方 向作射線
交點個數是奇數,則被測點在 多邊形內部
交點個數是偶數表示在多邊形外部
若射線正好經過多邊形的頂點,則 采用“左開右閉”的原則來實現
即:當射線與某條邊的頂點相交 時,若邊在射線的左側,交點有 效,計數;若邊在射線的右側, 交點無效,不計數
用射線法來判斷一個點是否在多邊形內的弊端:
(1)計算量大
(2)不穩定
(2)弧長法
以p點為圓心,作單位圓,把邊投影到單位圓上,對應一段段 弧長,規定逆時針為正,順時針為負,計算弧長代數和
代數和為0,點在多邊形外部
代數和為2π,點在多邊形內部
代數和為π,點在多邊形邊上
這個算法為什么是穩定的?
假如算出來后代數和不是0,而 是0.2或0.1,
那么基本上可以斷定這個點在外部,可以認為 是有計算誤差引起的,實際上是0。
但這個算法效率也不高,問題是算弧長並不容易,
因此又 派生出一個新的方法—以頂點符號為基礎的弧長累加方法
(3)以頂點符號為基礎的弧長累加方法
p是被測點,按照弧長法,p點 的代數和為2π
不要計算角度,做一個規定來 取代原來的弧長計算
同一個象限認為是 0,跨過一個象限是 π/2,跨過二個象限 是 π。
這樣當要計算代數和的時候,就不要去投影了,
只 要根據點所在的象限一下子就判斷出多少度,這樣幾乎沒 有什么計算量,只有一些簡單的判斷,效率非常高
小結
z-buffer算法是非常經典和重要的,在圖形加速卡和固件 里都有。
只用一個深度緩存變量zb的改進算法雖然減少了 空間,但仍然沒考慮相關性和連貫性