片段著色器中,內建gl_fragcoord向量的z值包含了那個特定片段的深度值。如果我們將這個深度值輸出為顏色,就可以顯示場景中所有片段的深度值。我們可以根據片段的深度值返回乙個顏色向量來完成這一工作:
void main()
如果執行程式的話,會注意到所有東西都是白色的,看起來就像所有的深度值都是最大的1.0。所以為什麼沒有靠近0.0(即變暗)的深度值呢?
你可能還記得在上一部分中說到,螢幕空間中的深度值是非線性的,即它在z值很小的時候有很高的精度,而z值很大的時候有較低的精度。片段的深度值會隨著距離迅速增加,所以幾乎所有的頂點的深度值都是接近於1.0的。如果我們小心地靠近物體,你可能會最終注意到顏色會漸漸變暗,顯示它們的z值在逐漸變小。這就是深度值的非線性性質。近處的物體比起遠處的物體對深度值有著更大的影響。只需要移動幾厘公尺就能讓顏色從暗完全變白。
然而,我們也可以讓片段非線性的深度值變換為線性的。要實現這個,我們需要僅僅反轉深度值的投影變換。這也就意味著我們需要首先將深度值從[0, 1]範圍重新變換到[-1, 1]範圍的標準化裝置座標(裁剪空間)。接下來我們需要像投影矩陣那樣反轉這個非線性方程,並將這個反轉的方程應用到最終的深度值上。最終的結果就是乙個線性的深度值了。
首先將深度值變換為ndc:
float z = depth * 2.0 - 1.0;
接下來使用獲取到的z值,應用逆變換來獲取線性的深度值:
float lineardepth = (2.0 * near * far) / (far + near - z * (far - near));
這個方程是用投影矩陣推導得出的,返回乙個near與far之間的深度值。
將螢幕空間中非線性的深度值變換至線性深度值的完整片段著色器如下:
#version 330 core
out vec4 fragcolor;
float near = 0.1;
float far = 100.0;
float linearizedepth(float depth)
void main()
由於線性化的深度值處於near與far之間,它的大部分值都會大於1.0並顯示為完全的白色。通過在main函式中將線性深度值除以far,我們近似地將線性深度值轉化到[0, 1]的範圍之間。這樣子我們就能逐漸看到乙個片段越接近投影平截頭體的遠平面,它就會變得越亮,更適用於展示目的。
如果我們現在執行程式,我們就能看見深度值隨著距離增大是線性的了。顏色大部分都是黑色,因為深度值的範圍是0.1的近平面到100的遠平面,它離我們還是非常遠的。結果就是,我們相對靠近近平面,所以會得到更低的(更暗的)深度值。
openGL學習筆記二十四 紋理迴圈滾動
通過每幀改變紋理uv座標實現紋理迴圈滾動。texturev 0.01f 這裡設定乙個矩形區域 並設定紋理uv座標 for int i 0 i 4 i 頂點資料 struct vertex 紋理id gluint texture float texturev 0 static fibitmap rea...
OpenGL學習二十七 混合
混合步驟 1.設定混合模式 2.啟用混合 glcolor4f 1.0f,1.0f,1.0f,0.5f 全亮度,50 alpha 混合 glblendfunc gl src alpha,gl one 基於源象素alpha通道值的半透明混合函式 glenable gl blend 開啟混合 opengl...
OpenGL學習筆記
我是一名ios開發者,opengl是乙個比較重要的技術。所以就此開啟我的菜鳥之路。opengl open graphics library 是乙個跨程式設計語 言 跨平台的程式設計圖形程式接 它將計算機的資源抽象稱為乙個個opengl的物件,對這些資源的操作抽象為乙個的opengl指令.direct...