2012-05-16 2 views
40

Когда вы изучаете 3D программирования, вас учат, что это самый простой думать в терминах матриц 3 преобразования:Почему было бы выгодно иметь отдельную матрицу проекции, но комбинировать модель и матрицу просмотра?

  1. матричная модель. Эта матрица индивидуальна для каждой модели, и она вращается и масштабирует объект по своему желанию и, наконец, перемещает его в свое конечное положение в вашем 3D-мире. «Модельная матрица преобразует координаты модели в мировые координаты».

  2. Матрица обзора. Эта матрица обычно одинакова для большого количества объектов (если не для всех), и она вращает и перемещает все объекты в соответствии с текущей «позицией камеры». Если вы визуализируете, что трехмерная сцена снимается камерой, а то, что отображается на экране, - это изображения, которые были захвачены этой камерой, местоположение камеры и направление ее просмотра определяют, какие части сцены видны и как объекты появляются на захваченном изображении. Есть мало причин менять матрицу представления при рендеринге одного кадра, но они действительно существуют (например, путем рендеринга сцены в два раза и изменения матрицы просмотра между ними, вы можете создать очень простое, но впечатляющее зеркало в вашей сцене) , Обычно матрица просмотра изменяется только один раз между двумя кадрами. «Матрица представления преобразует координаты мира в координаты глаз».

  3. Проекционная матрица. Проекционная матрица решает, как эти 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?

+6

Очень хорошо подробный вопрос. – JCM

ответ

31

Посмотрите на него практически. Во-первых, чем меньше матриц вы отправляете, тем меньше матриц вы должны размножаться с позициями/нормалями/и т. Д. И, следовательно, чем быстрее ваши шейдеры вершин.

Итак, точка 1: меньше матриц лучше.

Однако есть определенные вещи, которые вам, вероятно, понадобятся. Если вы не делаете 2D-рендеринг или некоторые простые 3D-приложения, вам нужно будет делать освещение. Обычно это означает, что вам нужно будет преобразовать позиции и нормали в пространство мира или камеры (просмотреть), а затем выполнить некоторые осветительные операции над ними (либо в вершинном шейдере, либо в шейдере фрагмента).

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

Итак, пункт 2: вам нужно как минимум остановка между моделью и проекцией.

Для этого нам нужно как минимум 2 матрицы. Почему модель-камера, а не модель-мир? Потому что working in world space in shaders is a bad idea. Вы можете столкнуться с численными проблемами точности, связанными с переводами, удаленными от начала координат. Принимая во внимание, что если вы работаете в космосе, вы не столкнетесь с этими проблемами, потому что ничего не слишком далеко от камеры (и, если это так, вероятно, должно быть за пределами дальней глубины).

Поэтому: мы используем пространство для камеры как промежуточное пространство для освещения.

+2

Освещение, конечно! Я вообще не думал о освещении. Вероятно, потому, что я никогда не писал собственный шейдер, который до сих пор выполняет какое-либо освещение. То, что вы не можете делать освещение в пространстве проецирования больше, кажется довольно логичным. – Mecki

+0

Кроме того, матричные операции с матрицами на графическом процессоре: * VERY * fast - iirc, у них есть специализированное оборудование, которое реализует его параллельно, поэтому полная матрица размером 4x4 на 4x4 составляет примерно такую ​​же стоимость, что и одна команда MAD (несколько тактовые циклы в худшем случае). Вам лучше всего ухаживать за фибрами, которые являются настоящими узкими местами. – imallett

+3

@Ian: Это чепуха; нет специального матричного матричного умножения. Для умножения 4x4 * 4x4 потребуется 16 циклов. Но это нормально, так как вам все равно не нужно это делать. Если вы просто трансформируете векторы (позиции или направления), вам нужно всего лишь выполнить умножение матрицы/вектора, которое занимает 4 цикла. –

2

В большинстве случаев вашему шейдеру понадобится геометрия в координатах мира или глаз для затенения, поэтому вам нужно отделить матрицу проекции от модели и просмотреть матрицы.

Создание вашего шейдера при умножении геометрии на две матрицы ухудшает производительность. Предполагая, что каждая модель имеет вершины с тысячами (или более), более эффективно вычислять матрицу представления модели в CPU один раз, и пусть шейдер выполняет одно меньшее умножение mtrix-вектора.

Смежные вопросы