来自 OpenGL 的归一化设备坐标金属

Normalized Device Coordinate Metal coming from OpenGL

好吧,所以我知道这里有很多关于规范化设备坐标的问题,但是 none 其中解决了我的特定问题。

所以,我绘制的所有内容都在 2D 屏幕坐标中指定,其中顶部、左侧是 (0,0),右下角是 (screenWidth, screenHeight) 然后在我的顶点着色器中我进行此计算以获取 NDC(基本上, 我正在渲染 UI 个元素):

float ndcX = (screenX - ScreenHalfWidth) / ScreenHalfWidth;
float ndcY = 1.0 - (screenY / ScreenHalfHeight);

其中 ScreenX/ScreenY 是像素坐标,例如 (600, 700) 并且 screenHalf_____ 是屏幕的一半 width/height。

而我return从顶点着色器的光栅化状态的最终位置是:

gl_Position = vec4(ndcX, ndcY, Depth, 1.0);

哪个在 Opengl ES 中工作得很好。

现在的问题是,当我在 Metal 2 中像这样尝试时,它不起作用。

我知道 Metal 的 NDC 是 2x2x1,而 Opengl 的 NDC 是 2x2x2,但我认为这里的深度在这个等式中没有发挥重要作用,因为我是在我自己的每个顶点中传递它。

我尝试了 this link and 但很困惑,链接也没有太大帮助,因为我试图避免在顶点着色器中进行矩阵计算,因为我现在正在渲染所有 2D 内容。

所以我的问题...在 Metal 中将像素坐标转换为 NDC 的公式是什么?是否可以不使用正交投影矩阵?为什么我的等式不适用于 Metal?

不用投影矩阵当然可以。矩阵只是应用转换的有用便利。但重要的是要了解它们在出现这种情况时如何工作,因为使用一般的正交投影矩阵会执行不必​​要的操作来获得相同的结果。

以下是我可能用来执行此操作的公式:

float xScale =  2.0f / drawableSize.x;
float yScale = -2.0f / drawableSize.y;
float xBias = -1.0f;
float yBias =  1.0f;

float clipX = position.x * xScale + xBias;
float clipY = position.y * yScale + yBias;

其中 drawableSize 是渲染缓冲区的尺寸(以像素为单位),可以在缓冲区中传递给顶点着色器。您还可以预先计算比例因子并传递这些比例因子而不是屏幕尺寸,以节省 GPU 上的一些计算。