OpenGL學習筆記(十四)深度測試

深度測試,就是unity中的層級,就是說定義他的層級,這樣纔不會出現多餘的渲染或不需要的圖形。
其實就是根據Z軸上的值,來判斷哪些片段被拋棄。
其實前面我們已經使用過深度測試了,就是下面這句代碼

	glEnable(GL_DEPTH_TEST);

使用這句代碼就能開啓深度測試。
我們來複習一下:
這是沒有開深度測試的效果圖:
在這裏插入圖片描述
這是開了深度測試的效果圖:
在這裏插入圖片描述
然後還有一句,禁止更新深度緩存區的代碼,只是用了這句代碼,我的程序就一片背景色,我也沒辦法得知到底是爲啥:

glDepthMask(GL_FALSE);

在這裏插入圖片描述
接下來就是glDepthFunc()了。
其有一堆的設置:

glDepthFunc(GL_ALWAYS);//總是通過深度測試,就是全部通過,跟沒開一樣,參考一號圖

	glDepthFunc(GL_LESS);//當片段深度小於深度緩衝區中的值時,通過測試,其實就是默認開啓時的設置,參考二號圖

	glDepthFunc(GL_NEVER);//永遠不能通過測試,就是一片背景色唄。一塊三角形都沒有渲染出來。參考三號圖


  	glDepthFunc(GL_EQUAL);//需要片段深度與深度緩衝區中的值相等時通過測試,參考三號圖

    glDepthFunc(GL_LEQUAL);//需要片段深度與深度緩衝區中的值小於相等時通過測試,參考二號圖

	glDepthFunc(GL_GREATER);//需要片段深度大於深度緩衝區中的值時通過測試,參考三號圖

	glDepthFunc(GL_NOTEQUAL);//需要片段深度與深度緩衝區中的值不相等時通過測試,參考一號圖

	glDepthFunc(GL_GEQUAL);//需要片段深度大於等於深度緩衝區中的值時通過測試,參考三號圖
深度值精度:就是我們將觀察空間中Z軸的,通過一種方式轉換到0到1之間,所給計算的精度。
當其比較近的時候,他的精度要求也就高,遠了要就應該低一些,所以我們不能使用線性的函數,
而應該選用非線性的函數。


重要的是要記住深度緩衝中的值在屏幕空間中不是線性的(在透視矩陣應用之前在觀察空間中是線性的)。深度緩衝中0.5的值並不代表着物體的z值是位於平截頭體的中間了,這個頂點的z值實際上非常接近近平面!

下面是深度測試的可視化:
先將FragmentSource.frag的最後一句改一下:

    FragColor = vec4(vec3(gl_FragCoord.z), 1.0);

在這裏插入圖片描述
我們就能夠發現所有的正方體都變成了白色,這是因爲屏幕空間中的深度值時非線性的,在z值較小時,精度很高,但z值較大時,精度就並不高。所以當距離拉遠時,屏幕空間中的深度值,也就全部都是接近於1的。而當你拉近視角時,你就能夠看見正方體的白色變暗了,這就是其深度值的變化。
如下圖:
在這裏插入圖片描述
因此我們需要的是從屏幕空間【0,1】轉換到我們的裁剪空間【-1,1】,再逆轉投影矩陣,得到我們要的線性深度值。
之後將片段着色器改成這樣。

#version 330 core
out vec4 FragColor;
float near = 0.1; 
float far  = 100.0; 

float LinearizeDepth(float depth) 
{
    float z = depth * 2.0 - 1.0; // 將屏幕空間的值轉到裁剪空間
    return (2.0 * near * far) / (far + near - z * (far - near));    //逆轉投影矩陣,具體的推導我不想了解,需要的時候再去了解吧
}

void main()
{             
    float depth = LinearizeDepth(gl_FragCoord.z) / far; // 爲了演示除以 far
    FragColor = vec4(vec3(depth), 1.0);
}

我們就得到了下面這個效果圖:
在這裏插入圖片描述
我們可以看到越近的正方體的顏色越深,也代表這他們的值越小。

還有就是當深度測試時,兩個貼圖靠的太近時,因爲其深度值太過接近,所以就有可能出現貼圖重疊的情況。
在這裏插入圖片描述

記錄一下,深度測試時的深度衝突的防止方法。
第一個也是最重要的技巧是永遠不要把多個物體擺得太靠近,以至於它們的一些三角形會重疊
第二個技巧是儘可能將近平面設置遠一些
另外一個很好的技巧是犧牲一些性能,使用更高精度的深度緩衝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章