gl_Position.w 在 Vulkan 中的作用是什么?

What is the role of gl_Position.w in Vulkan?

来自 GLSL 顶点着色器的变量 gl_Position 输出必须有 4 个坐标。在 OpenGL 中,似乎 w 坐标用于缩放向量,方法是将其他坐标除以它。 w 在 Vulkan 中的用途是什么?

Vulkan 中的着色器和投影与 OpenGL 中的行为完全相同。深度范围(OpenGL 中的 [-1, 1],Vulkan 中的 [0, 1])或坐标系原点(OpenGL 中的左下角,Vulkan 中的左上角)存在细微差异,但原理是完全一样的。硬件仍然相同,它在 OpenGL 和 Vulkan 中以相同的方式执行计算。

4 分量向量有多种用途:

  1. 可以进行不同的变换(平移、旋转、缩放) 以相同的方式表示,使用 4x4 矩阵。
  2. 投影也可以用 4x4 矩阵表示。
  3. 可以将多个变换组合成一个 4x4 矩阵。
  4. 你提到的.w组件在透视投影时使用。

所有这些我们都可以用 4x4 矩阵完成,因此我们需要 4 分量向量(因此它们可以乘以 4x4 矩阵)。同样,我写这篇文章是因为上述规则同时适用于 OpenGL 和 Vulkan。

因此,为了 gl_Position 变量的 .w 组件的目的 - 它在 Vulkan 中完全相同。它用于缩放位置向量 - 在透视计算(投影矩阵乘法)期间,原始深度由原始 .w 分量修改并存储在 gl_Position 变量的 .z 分量中。此外,原始深度也存储在 .w 组件中。之后(作为固定功能步骤)硬件执行透视除法并将存储在 gl_Position 变量中的位置除以其 .w 分量。

硬件执行的正交投影步骤完全相同,但用于计算的值不同。所以透视分割步骤仍然由硬件执行,但它什么都不做(位置被 1.0 潜水)。

在计算机图形学中,变换用矩阵表示。如果你想让某个东西旋转,你可以将它的所有顶点(一个向量)乘以一个旋转矩阵。想要它移动吗?乘以平移矩阵等

tl;dr: 您无法使用 3D 矩阵和向量描述沿 z 轴的平移。您至少还需要 1 个维度,因此他们只是添加了一个虚拟维度 w。但如果它不是 1,事情就会中断,所以将其保持在 1 :P.


无论如何,现在我们开始快速回顾一下矩阵乘法:

你基本上把x放在a上面,y放在b上面,z放在c上面。将整列乘以您刚刚移动的变量,然后对行中的所有内容求和。

所以如果你要翻译一个矢量,你会想要这样的东西:

看看 xy 现在是如何被 azbz 翻译的?不过这很尴尬:

  1. 每当你移动东西时,你都必须考虑 z 有多大(如果 z 是负数怎么办?你必须朝相反的方向移动。如果你只想把东西移一英寸...)
  2. 您不能沿 z 轴移动。你将永远无法飞行或进入地下

但是,如果您可以确保 z = 1 始终 :

现在更清楚了,该矩阵允许您在 x-y 平面中移动 ab 量。唯一的问题是你一直在概念上漂浮,你仍然不能上升或下降。你只能在 2D 中移动。

但是你看到这里的规律了吗?使用 3D 矩阵和 3D 矢量,您可以描述 2D 中的所有基本运动。那么如果我们添加第 4 个维度呢?

看起来很眼熟。如果我们一直保持 w = 1 :

我们开始了,现在您可以沿所有 3 个轴进行平移。这就是所谓的齐次坐标。

但是,如果您正在进行一些大而复杂的转换,导致 w != 1,并且没有办法解决它怎么办? OpenGL(以及我认为基本上任何其他 CG 系统)将执行所谓的归一化:将结果向量除以 w 分量。我不知道到底为什么('因为缩放是线性变换?),但它具有良好的含义(可用于透视变换)。无论如何,翻译矩阵实际上看起来像:

好了,看看每个组件如何缩小 w然后 它被翻译了?这就是 w 控制缩放的原因。

gl_Position 是一个 Homogeneous coordinatesw组件在透视投影中起作用。

投影矩阵描述了从场景视图的 3D 点到视口上的 2D 点的映射。它从眼睛space变换到剪辑space,剪辑space中的坐标通过除以剪辑坐标 (Perspective divide).

在透视投影中,投影矩阵描述了从针孔相机看到的世界中的 3D 点到视口的 2D 点的映射。
相机平截头体(截棱锥)中的眼睛 space 坐标映射到立方体(归一化设备坐标)。

透视投影矩阵:

r = right, l = left, b = bottom, t = top, n = near, f = far

2*n/(r-l)      0              0                0
0              2*n/(t-b)      0                0
(r+l)/(r-l)    (t+b)/(t-b)    -(f+n)/(f-n)    -1    
0              0              -2*f*n/(f-n)     0

当视图space中的笛卡尔坐标被透视投影矩阵变换时,结果是Homogeneous coordinatesw 组件随着到视点的距离而增长。这会导致对象在 Perspective divide 之后变得更小,如果它们离得更远的话。