天天看點

更深層次的深度測試(由混合所引出)

前言

學習混合的時候,偶然發現了深度測試存在的一些問題(也可以說是特性)。經過google之後明白了問題所在,對深度測試也有了進一步的了解。

更深層次的深度測試(由混合所引出)
更深層次的深度測試(由混合所引出)
更深層次的深度測試(由混合所引出)
更深層次的深度測試(由混合所引出)

如上所示,在進行混合的時候,發現有一些本該因為透明度混合出現的窗卻沒有出現,進一步觀察又會發現,有的透明度混合視窗卻照常出現。

結合前面的知識,我們可以聯想到,這是開啟了深度測試的結果。

在OpenGL中,物體的繪制順序是無序的。現在,我們不妨假設第一個視窗的深度是80,最後一個視窗的深度是100(并非值),并且先假設渲染第一個視窗:

z-buffer初始化為1.0, 第一個視窗的z-value小于1.0,此時Z-Write會将第一個視窗的depth-value(z-value)自動寫入Z-Buffer(也稱depth buffer),之後根據Z-Buffer渲染像素點。

接下來渲染第二個視窗,此時因為第二個視窗的z-value大于第一個視窗,是以Z-Write并不會将其深度值寫入Z-Buffer之中,也就不會去渲染它(即深度測試失敗)。

這就是上述情況出現的原因,當然,實際渲染由于是無序的,是以有時候我們可以看到視窗後面的視窗,有時候又看不到。

如何解決這種情況呢?能不能把深度測試關了?  顯然不能,對于一些不透明的物體,深度測試還是很有必要的。

是以我們從根源入手,可以考慮對半透明物體的渲染順序根據Z-value從大到小進行排序,也就是先渲染後面的物體,再渲染前面的物體,由于深度測試不能一次比較多個(三個以上)物體,我們可以很順利的将所有半透明物體在不受深度測試的影響下都繪畫出來。

還有一種方法,便是渲染半透明物體的時候,關閉深度寫入(深度緩沖先全初始化為1),這樣子也可以達到繪制所有物體的目的。

PS:如果物體深度之間有重疊的話,有些渲染順序會有誤(排序無用),這個時候關閉深度寫入,會使得渲染錯誤影響小很多。

  1. 先渲染不透明物體
  2. 根據Z值對半透明物體進行排序
  3. 渲染半透明物體

zhlabcd