作者:位元組流動
來源:
https://blog.csdn.net/Kennethdroid/article/details/101709694深度測試
OpenGL 深度測試是指在片段着色器執行之後,利用深度緩沖所儲存的深度值決定目前片段是否被丢棄的過程。
深度緩沖區通常和顔色緩沖區有着相同的寬度和高度,一般由視窗系統自動建立并将其深度值存儲為 16、 24 或 32 位浮點數。
當深度測試開啟的時候, OpenGL 才會測試深度緩沖區中的深度值。如果此測試通過,深度緩沖内的值可以被設為新的深度值;如果深度測試失敗,則丢棄該片段。
深度測試是在片段着色器運作之後(并且在模闆測試運作之後)在螢幕空間中執行的。
與螢幕空間坐标相關的視區是由 OpenGL 的視口設定函數 glViewport 函數給定,并且可以通過片段着色器中内置的 gl_FragCoord 變量通路。
gl_FragCoord 的 X 和 y 表示該片段的螢幕空間坐标 ((0,0) 在左下角),其取值範圍由 glViewport 函數決定,螢幕空間坐标原點位于左下角。
gl_FragCoord 還包含一個 z 坐标,它包含了片段的實際深度值,此 z 坐标值是與深度緩沖區的内容進行比較的值。
深度緩沖區中包含深度值介于 0.0 和 1.0 之間,物體接近近平面的時候,深度值接近 0.0 ,物體接近遠平面時,深度接近 1.0 。
(深度緩沖區的可視化)在片段着色器中将深度值轉換為物體顔色顯示:
#version 300 es
precision mediump float;
in vec2 v_texCoord;
layout(location = 0) out vec4 outColor;
uniform sampler2D s_TextureMap;
void main()
{
vec4 objectColor = vec4(vec3(gl_FragCoord.z), 1.0f);
outColor = objectColor;
}
顯示結果:

從圖中可以觀察到,靠近螢幕的物體顔色更黑(深度值更小),遠離螢幕的物體顔色更白(深度值更大)。
深度測試預設是關閉的,啟用深度測試使用
glEnable(GL_DEPTH_TEST);
。
啟用與不啟用深度測試時,繪制 3D 物體對比:
啟用深度測試 不啟用深度測試開啟深度測試後,如果片段通過深度測試,OpenGL 自動在深度緩沖區存儲片段的 gl_FragCoord.z 值,如果深度測試失敗,那麼相應地丢棄該片段。
如果啟用深度測試,那麼需要在渲染之前使用
glClear(GL_DEPTH_BUFFER_BIT);
清除深度緩沖區,否則深度緩沖區将保留上一次進行深度測試時所寫的深度值。
另外在一些場景中,我們需要進行深度測試并相應地丢棄片段,但我們不希望更新深度緩沖區,那麼可以設定深度掩碼
glDepthMask(GL_FALSE);
實作禁用深度緩沖區的寫入(隻有在深度測試開啟時才有效)。
OpenGL 深度測試是通過深度測試函數
glDepthFunc
控制深度測試是否通過和如何更新深度緩沖區。
深度測試函數接收的比較運算符:
深度測試啟用後,預設情況下深度測試函數使用
GL_LESS
,這将丢棄深度值高于或等于目前深度緩沖區的值的片段。
深度測試中,深度沖突現象需要值得注意。深度沖突(Z-fighting)是指兩個平面(或三角形)互相平行且靠近的過于緊密,模闆緩沖區不具有足夠的精度确定哪一個平面靠前,導緻這兩個平面的内容不斷交替顯示,看上去像平面内容争奪頂靠前的位置。
防止深度沖突的方法:
- 不要讓物體之間靠得過近,以免它們的三角形面片發生重疊;
- 把近平面設定得遠一些(越靠近近平面的位置精度越高);
- 犧牲一些性能,使用更高精度的深度值。
聯系與交流
技術交流、擷取源碼可以掃碼添加我的微信:Byte-Flow
「視訊雲技術」你最值得關注的音視訊技術公衆号,每周推送來自阿裡雲一線的實踐技術文章,在這裡與音視訊領域一流工程師交流切磋。