Почему было бы выгодно иметь отдельную матрицу проекции, но сочетать модель и матрицу просмотра?
Когда вы изучаете 3D-программирование, вас учат, что проще всего думать о трех матрицах преобразования:
-
Модельная матрица. Эта матрица индивидуальна для каждой модели, и она вращается и масштабирует объект по своему желанию и, наконец, перемещает его в свое конечное положение в вашем 3D-мире. "Модельная матрица преобразует координаты модели в мировые координаты".
-
Матрица просмотра. Эта матрица обычно одинакова для большого количества объектов (если не для всех), и она вращает и перемещает все объекты в соответствии с текущей "позицией камеры". Если вы визуализируете, что трехмерная сцена снимается камерой, а то, что отображается на экране, - это изображения, которые были захвачены этой камерой, местоположение камеры и направление ее просмотра определяют, какие части сцены видны и как объекты появляются на захваченном изображении. Есть мало причин менять матрицу представления при рендеринге одного кадра, но они действительно существуют (например, путем рендеринга сцены в два раза и изменения матрицы просмотра между ними, вы можете создать очень простое, но впечатляющее зеркало в вашей сцене), Обычно матрица просмотра изменяется только один раз между двумя кадрами. "Матрица представления преобразует мировые координаты в координаты глаз".
-
Матрица проецирования. Проекционная матрица решает, как эти 3D-координаты отображаются в 2D-координаты, например. если к ним применена перспектива (объекты становятся меньше, чем дальше от зрителя) или нет (ортогональная проекция). Проекционная матрица почти не меняется вообще. Возможно, это изменится, если вы визуализируетесь в окне, и размер окна изменился, или если вы выполняете полный экран, и разрешение изменилось, однако только в том случае, если новый размер окна/разрешение экрана имеет другой формат отображения, чем раньше. Есть некоторые сумасшедшие эффекты для того, что вы можете захотеть изменить эту матрицу, но в большинстве случаев ее довольно постоянную для всей жизни вашей программы. "Матрица проекции преобразует координаты глаз в координаты экрана".
Это делает для меня весь смысл. Конечно, всегда можно объединить все три матрицы в одну, поскольку умножение вектора сначала на матрицу A
, а затем на матрицу B
совпадает с умножением вектора на матрицу C
, где C = B * A
.
Теперь, если вы посмотрите на классический OpenGL (OpenGL 1.x/2.x), OpenGL знает матрицу проецирования. Однако OpenGL не предлагает модель или матрицу представлений, она предлагает только комбинированную матрицу модели. Почему? Эта конструкция заставляет вас постоянно сохранять и восстанавливать "матрицу просмотра", так как она будет "разрушена" с помощью преобразований модели, примененных к ней. Почему нет трех отдельных матриц?
Если вы посмотрите на новые версии OpenGL (OpenGL 3.x/4.x) и не используете классический конвейер рендеринга, но настройте все с помощью шейдеров (GLSL), матриц больше нет, вы должны определить свои собственные матрицы. Тем не менее, большинство людей придерживается старой концепции проекционной матрицы и матрицы модели. Зачем вам это делать? Почему бы не использовать три матрицы, что означает, что вам не нужно постоянно сохранять и восстанавливать матрицу просмотра модели или использовать единую комбинированную модель-представление-прогноз (MVP), которая сохраняет вам матричное умножение в вашем вершинном шейдере для рендеринга одиночной вершины (ведь такое умножение также не приходит бесплатно).
Итак, чтобы подвести итог моему вопросу: какое преимущество имеет комбинированная матрица модельного представления вместе с отдельной матрицей проектирования с тремя отдельными матрицами или одной матрицей MVP?
Ответы
Ответ 1
Посмотрите на это практически. Во-первых, чем меньше матриц вы отправляете, тем меньше матриц вы должны размножаться с позициями/нормалями/и т.д. И, следовательно, чем быстрее ваши шейдеры вершин.
Итак, точка 1: меньшее количество матриц лучше.
Однако есть определенные вещи, которые вам, вероятно, нужно делать. Если вы не делаете 2D-рендеринг или некоторые простые 3D-приложения, вам нужно будет делать освещение. Это обычно означает, что вам нужно будет преобразовать позиции и нормали в пространство мира или камеры (просмотреть), а затем выполнить некоторые осветительные операции над ними (либо в вершинном шейдере, либо в шейдере фрагмента).
Вы не можете этого сделать, если перейти только из пространства модели в пространство проецирования. Вы не можете делать освещение в пространстве постпроекции, потому что это пространство нелинейно. Математика становится намного сложнее.
Итак, пункт 2: вам нужна хотя бы одна остановка между моделью и проекцией.
Итак, нам нужно как минимум 2 матрицы. Почему модель-камера, а не модель-мир? Поскольку работает в мировом пространстве в шейдерах, это плохая идея. Вы можете столкнуться с численными проблемами точности, связанными с переводами, удаленными от источника. Принимая во внимание, что если вы работаете в космосе, вы не столкнетесь с этими проблемами, потому что ничего не слишком далеко от камеры (и, если это так, вероятно, должно быть за пределами дальней глубины).
Поэтому: мы используем пространство камеры как промежуточное пространство для освещения.
Ответ 2
В большинстве случаев вашему шейдеру понадобится геометрия в координатах мира или глаз для затенения, поэтому вам нужно отделить матрицу проекции от модели и просмотреть матрицы.
Создание вашего шейдера умножает геометрию на две матрицы, ухудшая производительность. Предполагая, что каждая модель имеет вершины с тысячами (или более), более эффективно вычислять матрицу вида модели в CPU один раз, и пусть шейдер делает одно меньшее умножение mtrix-вектора.