2017-03-19 183 views
1

我正在重建模板光着色器的位置。 這意味着我有光的球面近似的頂點,從中我可以得到一個世界空間視圖向量(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),但沒有奏效。

1 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「給出第一張圖像(移動相機時穩定),而原始功能給出第二張圖片(移動相機時非常不穩定)。

enter image description here enter image description here

+1

我不得不仔細檢查,但我猜測這是因爲NDC的Z從0變爲1而不是-1變爲1. –

回答

1

福爾康使用的深度範圍[0,1](並且實際上也翻轉Y軸),而不是OpenGL的[-1,1]。你有兩個選擇,讓OpenGL的類似行爲:

  • 可以通過在兩個
  • 或預乘你的投影矩陣相乘修復NDC的Z着色器,以符合OpenGL的方式,因爲你現在在做矩陣 1.0 0.0 0.0 0.0 0.0 -1.0 0.0 0.0 0.0 0.0 0.5 0.5 0.0 0.0 0.0 1.0

看一看https://matthewwellings.com/blog/the-new-vulkan-coordinate-system/瞭解更多詳情。 Vulkan規範(https://www.khronos.org/registry/vulkan/specs/1.0-wsi_extensions/html/vkspec.html#vertexpostproc-clipping)也有更多的細節,但沒有明確說明。

+0

謝謝,他對澄清有很多幫助,但有一些奇怪的問題仍在繼續。在[1,1]處使用沒有否定的矩陣確實有效,但是然後給出了倒置的y。然而,由於這種否定,我無法產生任何結果,屏幕保持黑色,就好像所有東西都被丟棄一樣。 – Aedoro

+0

你的相機可能只是朝着錯誤的方向呢?此外,有點相關,baldurk的renderdoc(https://renderdoc.org)是一個非常好的工具來調試這樣的問題。也許它可以幫助你弄清楚發生了什麼事。 – skalarproduktraum

+0

我看看那個,直到我找出顛倒的問題,我可以將我的向上的向量指向下,然後它也可以工作。 – Aedoro