2017-03-19 134 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