为什么 Vulkan 不使用 "standard cartesian" 坐标系?

Why doesn't Vulkan use the "standard cartesian" coordinate system?

Vulkan 使用坐标系,其中 (-1, -1) 位于左上象限,而不是通常在学校学习的标准笛卡尔坐标系中的左下象限。所以 (-1, 1) 在 Vulkan 的坐标系中位于左下象限。

(图片来自:http://vulkano.rs/guide/vertex-input

使用Vulkan的坐标系有什么优势?我可以看到的一个明显优势是教学方面的:它迫使人们认识到坐标系是任意的,并且可以轻松地在它们之间映射。但是,我怀疑这是设计原因。

那么这个选择的设计原因是什么?

计算机图形学中的许多坐标系将原点放在左上角,并将 y 轴指向下方。

这是因为在早期的电视机和显示器中,绘制图像的电子束从屏幕的左上角开始向下移动。

屏幕上的像素通常是通过在电子束沿屏幕向下移动时读取顺序地址中的存储器,并根据顺序读取的每个字节调制电子束来制作的。所以y轴对应的是时间,对应的是内存地址。

即使在今天,几乎所有位图在内存或位图文件中的表示都是从左上角开始的。

在这种介质中绘制位图时,自然也使用从左上角开始的坐标系。

当您使用左下原点时,事情会变得有点复杂,因为找到与像素对应的字节需要更多的数学运算,并且需要考虑位图的高度。通常没有理由引入额外的复杂性。

但是,当您开始引入矩阵变换时,使用向上指向的 y 轴会变得更加方便,因为这样您就可以使用在学校学到的所有向量代数,而无需反转 y 轴,并且你思想中的所有旋转。

所以你通常会发现,当你在一个允许你进行矩阵运算、平移、旋转等的系统中工作时,你会有一个向上的 y 轴。然而,在内部深处的某个点,计算会将坐标转换为向下的 y 轴以进行低级操作。

OpenGL 中常见的混淆和错误来源之一是 NDC 和 window 坐标向上增加,这与几乎所有 window 系统和许多(但不是所有)图像格式,其中 y 是 [0..1] 向下增加。在许多情况下,开发人员最终不得不在他们的转换管道中插入一个 y 翻转,而且他们何时插入和不插入并不总是很清楚。

因此 Vulkan 决定这样做,这样您就可以将 y 向下图像格式的图像直接加载到内存中并将其绘制到屏幕上,而无需任何明确的 y 翻转,以避免这种错误来源。

然后选择其他坐标系与此一致,因为 y 方向在标准 Vulkan 转换管道中永远不会翻转方向。这意味着剪辑 space 顶点坐标也有 y 向下增加。

这最终意味着 Vulkan 剪辑坐标与 D3D 剪辑坐标具有不同的方向,这对于支持这两种 API 的开发人员来说是一种烦恼。因此 VK_KHR_maintenance1 扩展添加了指定负视口高度的功能,这实质上是将 y 翻转引入了剪辑 - space 到帧缓冲区坐标变换。 (D3D 在这里基本上总是有一个隐式的 y 翻转。)

无论如何,这就是我记得 Vulkan 工作组中推理的方式。我认为任何地方都没有权威的 public 来源。