Понимание матрицы проекции libGDX

Последние несколько недель я пытался изучить библиотеку libGDX. Мне трудно, особенно для моей первой попытки разработки игр, понять систему отношений между камерой и областью просмотра. Одна строка кода, которую мне сказали использовать, и API упоминает:

    batch.setProjectionMatrix(camera.combined);

Несмотря на хорошие 4 часа исследований, мне все еще не хватает полного понимания функциональности этого кода. Насколько я понимаю, он «сообщает» партии, куда смотрит камера. Мое непонимание угнетает и злит, и я был бы признателен, если бы кто-нибудь мог мне помочь. Другая проблема с фрагментом кода заключается в том, что я не уверен, когда его необходимо реализовать (в методе рендеринга, методе создания и т. д.).


person user3059686    schedule 14.11.2015    source источник


Ответы (3)


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

Расположение скамьи на снимке относительно того, где вы стояли во время фотосъемки. Другими словами, это относительно камеры. В типичной игре вы не размещаете объект относительно объекта. Вместо этого вы помещаете их в свой игровой мир. Перевод между вашим игровым миром и вашей камерой осуществляется с помощью матрицы (это просто математический способ преобразования координат). Например. когда вы перемещаете камеру вправо, то скамья перемещается на фото влево. Это называется матрицей просмотра.

Точное расположение скамейки на картинке также зависит от расстояния между скамейкой и камерой. По крайней мере, в 3D (2D очень похоже, так что продолжайте читать). Когда он дальше, он меньше, когда он близко к камере, он больше. Это называется перспективной проекцией. Вы также можете иметь орфографическую проекцию, и в этом случае размер объекта не меняется в зависимости от расстояния до камеры. В любом случае расположение и размер скамейки в парке преобразуются в расположение и размер в пикселях на экране. Например. ширина скамейки в парке два метра, а на фото 380 пикселей. Это называется проекционная матрица.

camera.combined представляет комбинированную матрицу вида и проекции. Другими словами: он описывает, где элементы вашего игрового мира должны отображаться на экране.

Вызов batch.setProjectionMatrix(cam.combined); указывает пакету использовать эту комбинированную матрицу. Вы должны вызывать это всякий раз, когда значение изменяется. Обычно это происходит при вызове resize, а также всякий раз, когда вы перемещаете или иным образом изменяете камеру.

Если вы не уверены, вы можете вызвать это в начале вашего метода render.

person Xoppa    schedule 14.11.2015

Другой ответ отличный, но я полагаю, что другой способ его описания может помочь ему щелкнуть.

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

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

Вам редко приходится иметь дело с вещами в пространстве камеры в 2D, поэтому SpriteBatch не нуждается в отдельных матрицах вида и проекции. Их можно объединить в единую матрицу, которая преобразует прямо из мирового пространства в экранное пространство, что уже сделано автоматически в Камере, отсюда и матрица camera.combined.

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

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

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

person Tenfour04    schedule 14.11.2015

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

Вот пример: скажем, ваш экран имеет размер 100 пикселей * 100 пикселей (по какой-то причине). Вы помещаете объект в позицию (50, 0), так что теперь он находится посередине и внизу экрана. Теперь предположим, что вы перемещаете проигрыватель вправо, и весь экран перемещается вслед за игроком. Это означает, что объект, который вы разместили ранее, должен был сместиться влево на экране. Так что он по-прежнему находится в точке (50, 0) в мире, так как на самом деле он не двигался относительно остальной части пейзажа, но теперь он должен быть нарисован, скажем, в (10, 0) на экране, поскольку какая часть мир, на который смотрит экран, изменился. В этом разница между «мировым пространством» (где объект находится в мире) и «экранным пространством» (где объект отображается на фактическом дисплее).

Когда вы пытаетесь рисовать с помощью SpriteBatch, по умолчанию предполагается, что координаты мирового пространства совпадают с координатами экранного пространства: когда вы говорите «нарисовать в (50, 0)», он будет рисовать объект в (50, 0) на экране. Даже если камера движется, она всегда будет рисовать в точке (50, 0) на экране, поэтому при панорамировании камеры объект будет следовать за ним и оставаться на одном и том же месте на экране.

Поскольку обычно вы этого не хотите, вы даете SpriteBatch матрицу проекции, которая представляет собой матрицу преобразования, которая сообщает, как преобразовывать координаты экранного пространства в координаты мирового пространства и наоборот. Таким образом, когда вы говорите пакету «нарисовать в (50, 0)», он может посмотреть на матрицу, полученную от камеры, и увидеть, что, поскольку камера сдвинулась, (50, 0) в мире на самом деле означает ( 10, 0) на экране, и он отрисует ваш спрайт в нужном месте.

person Community    schedule 20.04.2016