零基礎學習OpenGL(三)--深度測試
深度緩衝:在每個片段中儲存了資訊,以16、24、32位float的形式儲存它的深度值。(片段著色器執行之後,在螢幕空間中執行。)
當深度測試啟用,OpenGL會將一個片段的深度值和深度緩衝的內容相比,如果測試通過,深度緩衝將更新為新的深度值;如果測試失敗,片段丟棄。
啟用深度測試:
glEnable(GL_DEPTH_TEST);
在每個渲染迭代之前清除深度緩衝:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
在某些情況下,如果我們只需要對所有片段深度測試並丟棄測試失敗的片段,而不希望更新深度快取的話,使用下面改為只讀:
glDepthMask(GL_FALSE);
深度測試函式:(我們來控制什麼時候通過或丟棄一個片段,什麼時候更新深度緩衝)
glDepthFunc(GL_LESS);
GL_LESS可以是下面的這些函式:
GL_ALWAYS | 永遠通過深度測試 |
GL_NEVER | 永遠不通過深度測試 |
GL_LESS | 在片段深度值小於緩衝的深度值時通過測試 |
GL_EQUAL | 在片段深度值等於緩衝區的深度值時通過測試 |
GL_LEQUAL | 在片段深度值小於等於緩衝區的深度值時通過測試 |
GL_GREATER | 在片段深度值大於緩衝區的深度值時通過測試 |
GL_NOTEQUAL | 在片段深度值不等於緩衝區的深度值時通過測試 |
GL_GEQUAL | 在片段深度值大於等於緩衝區的深度值時通過測試 |
舉個栗子:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_ALWAYS);
總是通過深度測試,那也就表示沒有深度測試,結果是最後繪製的就在之前繪製的上面。
而如果使用glDepthFunc(GL_LESS),結果為:
深度緩衝的值是0.0--1.0之間,但是觀察空間下z值為近平面到遠平面之間任意的值,需要將z值變換在0.0--1.0之間。公式如下:
在實踐中是幾乎永遠不會使用這樣的線性深度緩衝。要想有正確的投影性質,需要使用一個非線性的深度方程,它是與 1/z 成正比的。它做的就是在z值很小的時候提供非常高的精度,而在z值很遠的時候提供更少的精度。
深度衝突:深度值一樣的地方,深度緩衝沒有足夠的精度來決定兩個形狀哪個在前面。結果就是這兩個形狀不斷地在切換前後順序,這會導致很奇怪的花紋。
所以,不要把物體擺的太靠近,防止三角形重疊;近平面設定的遠一些,因為精度在靠近近平面的時候非常高,但是太遠會導致近處的被裁剪。