我正在重建模板光着色器的位置。 這意味着我有光的球面近似的頂點,從中我可以得到一個世界空間視圖向量(vertexPos - cameraPos)。的代碼看起來是這樣的:Vulkan深度緩衝區位置重構
vec3 construct_pos_ws(float depthBufferZ)
{
vec3 viewRay = normalize(gInVert.vRayWs);
float viewZDist = dot(gInFrame.eyeZAxis, viewRay);
vec3 relPoint = viewRay * linearDepth(depthBufferZ)/viewZDist;
return gInFrame.eye + relPoint;
}
vRayWs:世界空間視圖射線(內插vertexPos - 在vertexshader cameraPos) eyeZAxis:世界空間z軸的眼(照相機方向)
viewZDist:深度緩衝器保持一個平行於相機表面的距離,但我們需要一個距離,這說明了我們觀察物體的角度。
問題是與線性函數I使用,基於wikipedia: z-buffering: (I離開了S = 2^d-1,此部分似乎不適用)。
float linearDepth(float z_b) {
float f = z_far;
float n = z_near;
return (-f * n/(z_b (f - n) - f));
}
這是不行的,但使用float n = z_near * 2
而不是給出(貌似)正確的結果(我只是隨機嘗試,因爲以前的答案看起來接近正確)。
我試過其他線性化以及使用維基百科頁面上的所有樹變種的逆(低於3),但沒有奏效。
實際問題: 這是怎麼回事呢?爲什麼乘以2似乎給出了正確答案? Vulkan使用什麼公式來寫入深度緩衝區,因爲它似乎沒有使用wikipedia上的任何公式?
最後,完整性,投影矩陣結構是這樣的:
float yScale = 1.0f/tan(fov/2.0f);
float xScale = yScale/aspect;
float nearmfar = z_near - z_far;
Matrix m = {
xScale, 0, 0, 0,
0, yScale, 0, 0,
0, 0, (z_far + z_near)/nearmfar, -1,
0, 0, 2 * z_far * z_near/nearmfar, 0
};
而且,我怎麼知道它是正確的:
使用的變化,呈現「位置MOD 1「給出第一張圖像(移動相機時穩定),而原始功能給出第二張圖片(移動相機時非常不穩定)。
我不得不仔細檢查,但我猜測這是因爲NDC的Z從0變爲1而不是-1變爲1. –