Нормализованный металл координат устройства из OpenGL - PullRequest
0 голосов
/ 22 февраля 2019

Хорошо, я знаю, что здесь много вопросов, относящихся к нормализованным координатам устройства в SO, но ни один из них не касается моей конкретной проблемы.

Итак, все, что я рисую, указано в координатах 2D-экрана, гдесверху, слева (0,0), а справа снизу (screenWidth, screenHeight), затем в моем вершинном шейдере я делаю этот расчет, чтобы получить NDC (в основном, я рендеринг элементов пользовательского интерфейса):

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, это не работает.

Я знаю, что NDC у Metal - 2x2x1, а у Opengl - 2x2x2, но я думал, что глубина здесь не играет важной роли в этом уравнении, так как я передаю его в себя для каждой вершины.

Я пытался эта ссылка и этот вопрос , но был сбит с толку, и ссылки не были так полезны, так как я пытаюсь избежать матричных вычислений в вершинном шейдере, так какСейчас я отрисовываю все 2D.

Итак, мои вопросы ... Какова формула для преобразования координат пикселей в NDC в металле?Возможно ли это без использования матрицы ортографической проекции?Почему мое уравнение не работает для металла?

1 Ответ

0 голосов
/ 22 февраля 2019

Конечно, это возможно без проекционной матрицы.Матрицы - просто полезное удобство для применения преобразований.Но важно понимать, как они работают, когда возникают подобные ситуации, поскольку использование общей матрицы ортогональной проекции будет выполнять ненужные операции для достижения тех же результатов.

Вот формулы, которые я мог бы использовать для этого:

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 - размер (в пикселях) буфера рендеринга, который можно передать в буфере вершинному шейдеру.Вы также можете предварительно вычислить масштабные коэффициенты и передать их вместо размеров экрана, чтобы сохранить некоторые вычисления на графическом процессоре.

...