Как избежать субпиксельных значений в независимой от разрешения 2D-игре с ортогональной проекцией?

8

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

Согласно большинству учебных пособий, я могу свободно использовать любые размеры, которые мне нравятся, для усадки вида, но я обнаружил, что во многих случаях это приводит к проблеме, в результате которой я использую субпиксельные значения в области просмотра. Например, вершина в (62,62) в системе координат 960 x 540 заканчивается в (51.6666667,51.6666667) в области просмотра с размерами 800 x 450.

Я заметил два вида проблем с этим:

  • выборка текстуры все время изменяется для объектов, которые находятся в движении, в зависимости от того, где вершины расположены относительно центра пикселей
  • мои объекты растягиваются по горизонтали или вертикали на пиксель время от времени из-за округления

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

Эрик
источник
Как вы делаете изменение размера и переводы, чтобы вписаться в новый видовой экран? Матрицы? Ручное масштабирование и перемещение позиций объекта?
Эмир Лима
@EmirLima Я умножаю координаты на комбинированную матрицу вида-проекции-матрицы внутри моего вершинного шейдера. Все масштабирование выполняется матрицей ортографической проекции.
Эрик
Вы можете округлить или выровнять координаты (возможно, в vert shader)
t123
@ tm1rbrt Спасибо за ваш комментарий. Я думаю, что я должен был бы всегда или пол или потолок, чтобы избежать 1 пикселя больше или меньше в ширину или высоту. Я пытался сделать это внутри вершинного шейдера, но неточность в вычислениях делает это трудным, если не невозможным. Я закончил тем, что вывел идеальные целые числа на предыдущее целое число.
Эрик

Ответы:

1

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

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

В DirectX9 мне нужно было сделать это с HLSL, чтобы обойти причину, согласно которой углы текселя были расположены на 0,5, 0,5 относительно пикселя , делая четкие текстуры выглядящими полупрозрачными. Исправление этого изменяет физическое местоположение текселей, не перемещая вершины.

В вашем случае смещение будет варьироваться от кадра к кадру, поэтому передайте истинные координаты спрайта шейдеру, чтобы вычислить десятичное смещение. Не забудьте ЗАКРЫТЬ выборку текстур, чтобы избежать наложения текстур.

ChrisC
источник
3

Я думаю, что я буду хранить два набора координат.

  1. Один используется для рисования ваших объектов DISPLAY POSITIONи
  2. второй используется для хранения TRUE POSITION.

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

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

Джо
источник