[6].開啟Opengl的深度測(cè)試把

跳去目錄


(這里需要先完成demo5


深度緩沖(Depth buffer)

深度緩沖,也被叫做Z-緩沖,是用來存儲(chǔ)圖形所有片段的深度信息,在進(jìn)行3D圖形的繪制時(shí),每當(dāng)計(jì)算一個(gè)圖形片段,GLEW便會(huì)自動(dòng)生成一個(gè)深度作為這個(gè)片段的Z值(深度),而當(dāng)這個(gè)片段將要被渲染時(shí),OpenGL會(huì)將這個(gè)片段的深度與Z-深度進(jìn)行比較,通過比較,如果這個(gè)片段在其他片段的后面,那么這個(gè)片段將會(huì)被丟棄,不再渲染,也就不會(huì)再出現(xiàn)在屏幕上,反之,則渲染在屏幕上。

上述的這個(gè)過程稱之為深度測(cè)試(Depth Testing)

(話說外國(guó)人的取名思路真是新奇 0.0)

深度測(cè)試(Depth Testing)

? 在OpenGL中,深度測(cè)試是默認(rèn)關(guān)閉的(即在上下文深度測(cè)試是關(guān)閉的屬性),如果想要使用深度測(cè)試的功能,需要瘦瘦去打開它

glEnable(GL_DEPTH_TEST);

? 也正因?yàn)殚_啟了深度測(cè)試,所以在重新渲染其他圖形之前,我們需要清空深度緩沖區(qū)中間的數(shù)據(jù),不然后續(xù)的深度測(cè)試會(huì)有影響.

glClear(GL_DEPTH_BUFFER_BIT);

深度緩沖區(qū)中的每一個(gè)緩沖都是有有精度的,通常,深度緩沖的精度以16、24、32位的float形式進(jìn)行存儲(chǔ),一般情況下,都是以24位的精度進(jìn)行存儲(chǔ)的。在早期的游戲中,是以16位的精度進(jìn)行存儲(chǔ)的,這樣會(huì)產(chǎn)生一個(gè)問題,當(dāng)畫面數(shù)據(jù)過于龐大時(shí),深度緩沖區(qū)中的緩存值會(huì)存在相同的數(shù)據(jù)(數(shù)據(jù)特別大的時(shí)候),這時(shí)候OpenGL就不再能分辨正面背面,而產(chǎn)生類似于穿模的狀況,這時(shí)候提升精度就解決這個(gè)問題了。

? 但是并不是精度越高就越好,精度越高,單個(gè)深度緩沖占據(jù)的空間就越大,處理起來就越復(fù)雜,對(duì)配置的要求就越高

深度測(cè)試函數(shù)

(在深度測(cè)試啟用時(shí),深度測(cè)試函數(shù)才會(huì)起效果。)

OpenGL在進(jìn)行深度測(cè)試時(shí),會(huì)通過特定的深度測(cè)試函數(shù)來進(jìn)行數(shù)據(jù)的運(yùn)算并更新深度緩沖,我們可以調(diào)用glDepthFunc函數(shù)來設(shè)置比較運(yùn)算符(或者說深度函數(shù)(Depth Function)

//GL_ALWAYS 深度函數(shù)
glDepthFunc(GL_ALWAYS);

深度函數(shù)可以改為下表中的函數(shù)(實(shí)際上每個(gè)深度函數(shù)都是一系列的計(jì)函數(shù)計(jì)算)

深度函數(shù)

深度值精度

深度緩沖是由一系列0.0-1.0的深度值所構(gòu)成的,這個(gè)值可以是投影平截頭體的近平面(Near)和遠(yuǎn)平面(Far)之間的任何值,通過片段自身的z坐標(biāo)與near和far,可以粗略的計(jì)算出這個(gè)片段的深度值,基于OpenGL,這個(gè)值位于0.0-1.0之間,F_{depth} = \frac{z - near}{far - near},這里的near和far是之前設(shè)置投影矩陣的時(shí)候設(shè)置的。

遠(yuǎn)近平面

但是這個(gè)公式是線性的,實(shí)際上幾乎永遠(yuǎn)不會(huì)使用這樣的數(shù)學(xué)模型,因?yàn)槲覀冃枰氖?,在z離的很近的時(shí)候要提供足夠的精度以供OpenGL渲染視圖,在z離的很遠(yuǎn)的時(shí)候只需要很小的精度用于判斷是否需要抹去,也就是需要設(shè)置為 \frac{1}{z} 的數(shù)學(xué)模型,因此,可以考慮將深度值的計(jì)算模型替換為 F_{depth} = \frac{1/z - 1/near}{1/far - 1/near} ,這樣就能夠滿足我們的條件了。

深度沖突

深度沖突(Z-fighting)是指兩個(gè)平面或三角形很緊密的平行排列在一起時(shí)(理解為重合吧),深度精度不足以去判斷它們的深度,所以深度測(cè)試并不能判斷哪個(gè)應(yīng)該顯示,哪個(gè)應(yīng)該抹去,所表現(xiàn)出來的結(jié)果是,兩個(gè)片段不斷的重復(fù)交替出現(xiàn)消失(玩CS的小伙伴應(yīng)該遇到過很多次了),這種現(xiàn)象并不能夠完全的避免,就算是提高了精度值,在數(shù)據(jù)量足夠龐大的時(shí)候依然有可能會(huì)出現(xiàn)這樣的問題(就算1080的不夠,還有2K,4K,甚至未來的8K,16K的游戲呢 =。=),對(duì)于這種情況,有一些技巧可以防止其產(chǎn)生。

  • 在放置物體時(shí),不要講物體放置的太靠近
  • 適量的去調(diào)整近平面的位置
  • 使用更更高的精度(但會(huì)對(duì)性能產(chǎn)生影響,畢竟計(jì)算的開銷更大)
    基本上,將上面的三種方式結(jié)合起來使用,也能夠解決目前的深度沖突問題了,以后技術(shù)更新了,自然會(huì)有其他的方式來解決這個(gè)問題~

跳去目錄

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

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