天天看點

詳細介紹Z-Buffer與W-Buffer

depth-buffer(深度緩存)有兩種:z-buffer 和 w-buffer,這裡讨論這兩種深度緩存的差別,以及如何在兩者之間轉換。

w 的含義

3d空間點的坐标是(x,y,z),為了使矩陣乘法具有平移變換的功效,我們用4d空間中的點(x,y,z,w)來表示3d空間中的點(x',y',z'),這兩個不同空間點之間的關系是:

x' = x / w

y' = y / w

z' = z / w

像這樣用四維空間點表示三維空間點,或者說用 n + 1 維空間點表示 n 維空間點的方法叫做 “齊次坐标表示法”。

實際使用中,在模型->世界轉換、世界->視圖轉換過程中,w 通常保持不變,總是等于一,這樣,齊次坐标的前三個分量就是對應3d空間點的三個坐标分量。但是,經過投影變換後,w 将得到一個比例值,比如,一般的透視投影變換矩陣是:

| w  0  0  0 |

| 0  h  0  0 |

| 0  0  q  1 |

| 0  0 -qzn 0 |

其中  zn = 近裁剪面 z 坐标

zf = 遠裁剪面 z 坐标

w = 2 * zn / 視口寬度

h = 2 * zn / 視口高度

q = zf / (zf - zn)

将點(x,y,z,1)乘以此矩陣,w 便不再是一,而對應的3d空間點坐标(x / w,y / w,z / w)将出現一個縮放效果。同時,因為 w 的值通常與 z 坐标成正比(比如經過上面這個矩陣的變換,w 的值其實就是 z 坐标的值),是以經過投影變換,物體會産生近大遠小的效果。

z-buffer 與 w-buffer 的差別

簡單的說,z-buffer 與 w-buffer 的差別就是前者儲存的是點的 z 坐标,而後者儲存的是點的 w 坐标。

具體的說,兩者因為儲存的值有不同的含義,是以表現出來的實際效果也會有差别。

z-buffer 儲存的是經過投影變換後的 z 坐标,前面說過,投影後物體會産生近大遠小的效果,是以距離眼睛比較近的地方,z 坐标的分辨率比較大,而遠處的分辨率則比較小,換句話說,投影後的 z 坐标在其值域上,對于離開眼睛的實體距離變化來說,不是線性變化的(即非均勻分布),這樣的一個好處是近處的物體得到了較高的深度分辨率,但是遠處物體的深度判斷可能會出錯。

w-buffer 儲存的是經過投影變換後的 w 坐标,而 w 坐标通常跟世界坐标系中的 z 坐标成正比,是以變換到投影空間中之後,其值依然是線性分布的,這樣無論遠處還是近處的物體,都有相同的深度分辨率,這是它的優點,當然,缺點就是不能用較高的深度分辨率來表現近處的物體。

從硬體實作角度來說,幾乎所有的硬體3d加速卡都支援 z-buffer,而 w-buffer 的支援沒有 z-buffer 那麼廣泛。另外,早期的 direct3d 版本看起來也不支援 w-buffer。

z-buffer 與 w-buffer 之間的轉換

根據上面的矩陣變換,可以很容易的導出将 w-buffer 轉換成 z-buffer 的公式:

zdepth = q * ( wdepth - zn ) / wdepth

= zf / ( zf - zn ) * ( wdepth - zn ) / wdepth

這個轉換公式有什麼用處?舉個例子:3ds max 使用的是 w-buffer,如果從 3ds max 中導出深度資訊到 direct3d 中,作為預渲染的背景使用,就有可能用到上面這個轉換。當然,如果在 d3d 中使用 w-buffer,問題就不大了,但是如果使用 z-buffer,不經過這樣的轉換,渲染結果就會出錯。

簡介:09年入行,喜歡遊戲和程式設計,對3d遊戲和引擎尤其感興趣。 

版權聲明:本文版權歸作者和部落格園共有,歡迎轉載。轉載必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

轉載:http://www.cnblogs.com/geniusalex/archive/2010/04/26/1940510.html

繼續閱讀