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

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

    batch.setProjectionMatrix(camera.combined);

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

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

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

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

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