齐次坐标和透视正确性?

Homogeneous coordinates and perspective-correctness?

vulkan 使用的技术(我假设还有其他图形库)以透视正确的方式插入顶点属性是否要求顶点着色器必须标准化同质相机-space 顶点位置(即:除以 w 坐标,使 w 坐标为 1.0),然后再乘以形式为...

的典型投影矩阵
 g/s  0    0         0
  0   g    0         n
  0   0    f/(f-n)   -nf/(f-n)
  0   0    1         0

...为了使透视正确性正常工作?

或者,透视正确性是否会继续作用于相机中的任何同质顶点位置 -space(w 坐标不是 1.0)?

(我没有完全遵循透视正确性数学,所以我不清楚哪个是正确的。)

更新:

为了澄清术语:

vec4 modelCoordinates = vec4(x_in, y_in, z_in, 1);
mat4 modelToWorld = ...;
vec4 worldCoordinates = modelToWorld * modelCoordinates;
mat4 worldToCamera = ...;
vec4 cameraCoordinates = worldToCamera * worldCoordinates;
mat4 cameraToProjection = ...;
vec4 clipCoordinates = cameraToProjection * cameraCoordinates;
output(clipCoordinates);

cameraToProjection 是一个类似于问题中所示的矩阵

问题是 cameraCoordinates.w 必须是 1.0 吗?

因此 modelToWorldworldToCamera 矩阵的最后一行必须是 0 0 0 1?

你完全倒过来了。在着色器中进行透视划分是 防止 透视正确插值的原因。光栅化器需要 W 组件提供的透视信息来完成它的工作。 W 为 1 时,插值在 window space 中完成,不考虑透视。

为顶点处理阶段的输出提供一个剪辑-space坐标,让系统做它存在的事情。


the vertex shader must normalize the homogenous camera-space vertex position (ie: divide through by the w-coordinate such that the w-coordinate is 1.0) prior to multiplication by a typical projection matrix of the form...

如果您的相机-space 顶点位置的 W 不是 1.0,那么会发生以下两种情况之一:

  1. 你故意在一个post-投射世界space或一些类似的结构中运作。这是一件完全有效的事情,相机的数学运算 space 可以完全合理。

  2. 您的代码某处有问题。也就是说,你打算让你的世界和相机space成为一个正常的、欧几里德的、非均匀的space,但不知何故数学没有成功.显然,这不是一件完全有效的事情。

在这两种情况下,除以 W 都是错误的做法。如果你放置相机的世界space是post投影(例如in this example),除以W将破坏你的透视校正插值,如上所述。如果您的代码有问题,除以 W 只会 掩盖 实际问题;修复代码比隐藏错误更好,因为它可能会突然出现在其他地方。

为了看相机坐标是否需要正常形式,让我们将相机坐标表示为w的倍数,所以它们是(wx,wy,wz,w)

乘以给定的投影矩阵,我们得到剪辑坐标(wxg/s, wyg, fwz/(f-n)-nfw/(f-n)), wz)

根据固定的 Vulkan 公式计算 x-y 帧缓冲区坐标,我们得到 (P_x * xg/sz +O_x, P_y * Hgy/z + O_y)。请注意,这不依赖于 w,因此多边形顶点在帧缓冲区中的位置不需要摄像机坐标为正常形式。

同样计算多边形内片段的重心坐标仅取决于帧缓冲区坐标中的x,y,因此也独立于w

然而,片段属性的透视正确透视插值确实取决于顶点的 W_clip,因为 Vulkan 规范中给出的公式中使用了这一点。如上所示 W_clipwz,它确实依赖于 w 并与之成比例,因此我们可以得出结论,相机坐标必须是正常形式(它们的 w 必须是 1.0)