【问题标题】:Vulkan depth buffer position reconstructionVulkan 深度缓冲区位置重建
【发布时间】:2017-03-19 05:54:54
【问题描述】:

我正在重建模板灯光着色器的位置。 这意味着我有用于光的球面近似的顶点,我可以从中获得世界空间视图矢量(vertexPos - cameraPos)。代码如下所示:

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 - 顶点着色器中的cameraPos) eyeZAxis :眼睛的世界空间 z 轴(相机方向)
viewZDist :深度缓冲区保持与相机表面平行的距离,但我们需要一个距离,这说明了我们查看对象的角度。


问题在于我使用的线性化函数,基于wikipedia: z-buffering: (我省略了 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 使用什么公式来写入深度缓冲区,因为它似乎没有使用维基百科上的任何公式?


最后,为了完整起见,投影矩阵的构造是这样的:

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
};

另外,我怎么知道它是正确的:

使用更改和渲染“position mod 1”给出第一张图像(移动相机时稳定),而原始函数给出第二张图片(移动相机时非常不稳定)。

【问题讨论】:

  • 我必须仔细检查,但我猜这是因为 NDC 的 Z 从 0 变为 1,而不是从 -1 变为 1。

标签: graphics rendering shader vulkan


【解决方案1】:

Vulkan 使用 [0, 1] 的深度范围(实际上还翻转了 Y 轴),而不是 OpenGL 的 [-1, 1]。您有两种选择来获得类似 OpenGL 的行为:

  • 修复着色器中的 NDC Z 以符合 OpenGL 方式,就像您现在通过乘以 2 所做的那样
  • 或将投影矩阵与矩阵预乘 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) 也有更多细节,但没有明确说明。

【讨论】:

  • 谢谢你,他的澄清帮助很大,但仍有一些奇怪的问题。在 [1,1] 处使用没有否定的矩阵确实有效,但随后给出了倒置的 y。然而,由于这种否定,我无法产生任何结果,屏幕保持黑色,好像所有东西都被丢弃了。
  • 你的相机可能只是朝向错误的方向吗?此外,在某种程度上,baldurk 的 renderdoc (renderdoc.org) 是调试此类问题的绝佳工具。也许它可以帮助你弄清楚发生了什么。
  • 我会看看那个,直到我弄清楚颠倒的问题,我可以将我的向上向量指向下方,然后它也可以工作。
猜你喜欢
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
  • 1970-01-01
相关资源
最近更新 更多