1973年,猶他大學學生艾德·卡姆爾(Edwin Catmull)獨 立開發出了能跟蹤屏幕上每一個像素深度的算法 Z-buffer算法
Z-buffer讓計算機生成複雜圖造成爲可能。Ed Catmull目 前擔任迪士尼動畫和皮克斯動畫工做室的總裁數組
Z緩衝器算法也叫深度緩衝器算法,屬於圖像空間消隱算法緩存
該算法有幀緩衝器和深度緩衝器。對應兩個數組:動畫
intensity(x,y)——屬性數組(幀緩衝器)blog
存儲圖像空間每一個可見像素的光強或顏色開發
depth(x,y)——深度數組(z-buffer)it
存放圖像空間每一個可見像素的z座標class
假定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)處 } } } }
(1)Z-Buffer算法比較簡單,也很直觀
(2)在象素級上以近物取代遠物。與物體在屏幕上的出現 順序是可有可無的,有利於硬件實現
(1)佔用空間大
(2)沒有利用圖形的相關性與連續性,這是z-buffer算法 的嚴重缺陷
(3)更爲嚴重的是,該算法是在像素級上的消隱算法
通常認爲,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的平面方程爲:
由被測點P處向 y = -∞方 向做射線
交點個數是奇數,則被測點在 多邊形內部
交點個數是偶數表示在多邊形外部
若射線正好通過多邊形的頂點,則 採用「左開右閉」的原則來實現
即:當射線與某條邊的頂點相交 時,若邊在射線的左側,交點有 效,計數;若邊在射線的右側, 交點無效,不計數
用射線法來判斷一個點是否在多邊形內的弊端:
(1)計算量大
(2)不穩定
以p點爲圓心,做單位圓,把邊投影到單位圓上,對應一段段 弧長,規定逆時針爲正,順時針爲負,計算弧長代數和
代數和爲0,點在多邊形外部
代數和爲2π,點在多邊形內部
代數和爲π,點在多邊形邊上
這個算法爲何是穩定的?
假如算出來後代數和不是0,而 是0.2或0.1,
那麼基本上能夠判定這個點在外部,能夠認爲 是有計算偏差引發的,其實是0。
但這個算法效率也不高,問題是算弧長並不容易,
所以又 派生出一個新的方法—以頂點符號爲基礎的弧長累加方法
p是被測點,按照弧長法,p點 的代數和爲2π
不要計算角度,作一個規定來 取代原來的弧長計算
同一個象限認爲是 0,跨過一個象限是 π/2,跨過二個象限 是 π。
這樣當要計算代數和的時候,就不要去投影了,
只 要根據點所在的象限一會兒就判斷出多少度,這樣幾乎沒 有什麼計算量,只有一些簡單的判斷,效率很是高
z-buffer算法是很是經典和重要的,在圖形加速卡和固件 裏都有。
只用一個深度緩存變量zb的改進算法雖然減小了 空間,但仍然沒考慮相關性和連貫性