OpenGL-深度測試

通過上一篇OpenGL-正背面剔除的分析,我們知道要想更好的解決隱藏面消除,并且不引發(fā)其他問題,我們只能探尋其他的方法--即本節(jié)的深度測試
下面先來了解幾個概念

什么是深度?

深度就是像素點在3D世界中距離攝像機的距離,Z值。觀察者可以放在坐標系的任何位置,所以不能簡單的說Z值越大或越小,觀察者就距離物體越近
深度值的精度一般有16位,24位或者36位,位數(shù)越高,深度的精確度越好。一般是24位精度。

什么是深度緩沖區(qū)?

深度緩沖區(qū)就是一塊內(nèi)存區(qū)域,用來存儲每個像素點的深度值

為什么需要深度緩沖區(qū)?

在不使用深度緩沖區(qū)的時候,如果我們先繪制距離近的物體,再繪制距離遠的物體,那么重合區(qū)域就會出現(xiàn):距離遠的物體覆蓋距離近的物體的現(xiàn)象。但是有了深度緩沖區(qū)之后,繪制順序就沒有那么重要了,深度緩沖區(qū)會根據(jù)設置的參數(shù),存儲需要繪制的像素點對應的深度值(每個像素點只會存儲一個對應的深度值,或是近的,或是遠的,中間會涉及深度值的替換等),并且或同步更新該像素點對應的顏色值(深度緩存區(qū)跟顏色緩存區(qū)一一對應),這個過程就是所謂的深度測試

如何使用深度測試?

OpenGL提供了對應的API

//開啟深度測試
glEnable(GL_DEPTH_TEST);

注意:在繪制場景前,需要清除深度緩沖區(qū)和顏色緩沖區(qū)

//設置顏色
glClearColor(0.0f,0.0f,0.0f,1.0f);
//清理緩沖區(qū)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//深度緩沖區(qū)默認值為1.0,表示最?大的深度值,深度值的范圍為(0,1)之間. 

在深度測試之前,我們可以設置深度測試的判斷模式

//指定深度測試判斷模式
void glDepthFunc(GLEnum mode);
深度測試的判斷模式.png

這個設置并不常用,一般使用系統(tǒng)的默認值就足夠

我們還可以打開/阻斷深度緩沖區(qū)的寫入

//value : GL_TURE 開啟深度緩沖區(qū)寫?入; GL_FALSE 關(guān)閉深度緩沖區(qū)寫?入
void glDepthMask(GLBool value);
深度測試解決了什么問題?

使用深度測試代替正背面剔除,我們即消除了隱藏面,又不會導致圖像的重合區(qū)域出現(xiàn)缺失一塊的問題


隱藏面消除.png

重疊區(qū)域正常顯示.png
深度測試的弊端?

潛在風險:ZFighting閃爍問題

  • 因為開啟深度測試后,OpenGL 就不會再去繪制模型被遮擋的部分. 這樣實現(xiàn)的顯示更加真實.但是由于深度緩沖區(qū)精度的限制,對于深度相差非常小的情況下.(例如在同?平面上進行2次繪制),OpenGL就可能出現(xiàn)不能正確判斷兩者的深度值,會導致深度測試的結(jié)果不可預測.顯示出來的現(xiàn)象是交錯閃爍.前面2個畫面,交錯出現(xiàn).
    1.png
    2.png
那么如何解決呢?

對于這個問題,我們可以通過啟? Polygon Offset ?式解決。即讓深度值之間產(chǎn)?間隔.如果2個圖形之間有間隔,是不是意味著就不會產(chǎn)?干涉.可以理解為在執(zhí)行深度測試前將?方體的深度值做一些細微的增加.于是就能將重疊的2個圖形的深度值有所區(qū)分.

//啟用Polygon Offset
glEnable(GL_POLYGON_OFFSET_FILL)
//參數(shù)列表: 
//GL_POLYGON_OFFSET_POINT  對應光柵化模式: GL_POINT
//GL_POLYGON_OFFSET_LINE  對應光柵化模式: GL_LINE
//GL_POLYGON_OFFSET_FILL  對應光柵化模式: GL_FILL

//指定偏移量
void glPolygonOffset(Glfloat factor,Glfloat units);
//應用到?段上總偏移計算?方程式:
//Depth Offset = (DZ * factor) + (r * units); 
//DZ:深度值(Z值)
//r:使得深度緩沖區(qū)產(chǎn)生變化的最?值,具體是由OpenGL平臺指定的 ?個常量.
//負值,將使得z值距離我們更近,?正值,將使得z值距離我們更遠.
//一般?言,只需要將-1.0 和 -1 這樣簡單賦值給glPolygonOffset 基本可以滿?需求.

//關(guān)閉Polygon Offset 
glDisable(GL_POLYGON_OFFSET_FILL)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容