来自OpenGL的标准化设备坐标金属

问题描述 投票:0回答:1

好吧,所以我知道在SO上有很多关于标准化设备坐标的问题,但它们都没有解决我的特定问题。

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

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

其中ScreenX / ScreenY是像素坐标,例如(600,700),screenHalf_____是屏幕宽度/高度的一半。

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

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

哪个在Opengl ES中运行得非常好。

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

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

我尝试了this linkthis so question但是很困惑,因为我试图避免顶点着色器中的矩阵计算,因为我现在正在渲染所有2D,因此链接没有用。

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

math matrix 3d opengl-es metal
1个回答
1
投票

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

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

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上保存一些计算。

© www.soinside.com 2019 - 2024. All rights reserved.