gl_Position.w在Vulkan中起什么作用?

时间:2018-07-13 05:20:40

标签: glsl vulkan

GLSL顶点着色器的

变量gl_Position输出必须具有4个坐标。在OpenGL中,似乎w坐标用于将向量除以其他坐标来缩放向量。 w在Vulkan中的用途是什么?

3 个答案:

答案 0 :(得分:4)

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。

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

由硬件执行的正交投影步骤完全相同,但是用于计算的值不同。因此,透视图划分步骤仍由硬件执行,但不执行任何操作(位置由1.0代替)。

答案 1 :(得分:2)

gl_PositionHomogeneous coordinatesw组件在透视投影中起作用。

投影矩阵描述从场景中的视图的3D点到视口上的2D点的映射。它从眼睛空间转换到剪辑空间,并且通过除以剪辑坐标(Perspective divide)的w分量,将剪辑空间中的坐标转换为归一化设备坐标(NDC)。 / p>

在“透视投影”中,投影矩阵描述了从针孔相机看到的世界3D点到视口的2D点的映射。
摄像机视锥中的眼睛空间坐标(截断的金字塔)映射到立方体(规范化的设备坐标)。

Perspective Projection

透视投影矩阵:

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

当透视投影矩阵转换视图空间中的Cartesian coordinate时,结果为Homogeneous coordinatesw分量随着到视点的距离而增长。这导致对象在Perspective divide之后变小(如果它们距离较远)。

答案 2 :(得分:0)

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

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


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

Matrix multiplication

您基本上将x放在a上方,将y放在b上方,将z放在c上方。将整个列乘以您刚刚移动的变量,然后将行中的所有内容相加。

因此,如果要翻译矢量,则需要类似以下内容的

enter image description here

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

  1. 每次移动东西时,您都必须考虑z的大小(z是否为负值?您必须朝相反的方向移动。想要移动一英寸...)
  2. 您不能沿z轴移动。您将永远无法飞行或进入地下

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

enter image description here

现在,更加清楚的是,该矩阵允许您在x-y平面上移动ab数量。唯一的问题是,从概念上讲,您一直都在悬浮,但仍然无法上下移动。您只能以2D模式移动。

但是您在这里看到一个模式吗?使用3D矩阵和3D向量,您可以描述2D中的所有基本运动。那如果我们添加第4维呢?

enter image description here

看起来很熟悉。如果我们始终保持w = 1

enter image description here

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

但是,如果您进行了一些大而复杂的转换,结果是w != 1,该怎么办呢? OpenGL(我认为基本上是所有其他CG系统)都将执行标准化:将结果矢量除以w分量。我还不足以确切地说出原因(“缩放是线性变换吗?”),但是它具有有利的含义(可以在透视变换中使用)。无论如何,翻译矩阵实际上看起来像:

enter image description here

接下来,看看w如何压缩每个组件,然后然后进行翻译?这就是w控制缩放的原因。