好的,所以我知道在SO上有很多关于规范化设备坐标的问题,但是这些问题都没有解决我的特定问题。
因此,我绘制的所有内容均在2D屏幕坐标中指定,其中top,left为(0,0),右下为(screenWidth,screenHeight),然后在我的顶点着色器中进行此计算以得出NDC(基本上,我'm渲染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 link和this so question,但感到困惑,并且链接并不是那么有用,因为由于我现在正在渲染所有2D图像,所以我试图避免在顶点着色器中进行矩阵计算。>
所以我的问题...在Metal中将像素坐标转换为NDC的公式是什么?是否可以不使用正交投影矩阵?为什么我的方程式不适用于Metal?
答案 0 :(得分: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上的一些计算。