Оптимизация игры XNA 2D

56

Имеет ли смысл реализовывать логику, чтобы пропустить рендеринг объектов за пределами области просмотра, или мне не нужно заботиться об этом и позволить Framework сделать это?

smnbss
источник

Ответы:

79

Отбраковка - это оптимизация производительности. Так что не имеет смысла просто делать это ради этого. У тебя должна быть причина.


Графический процессор (не XNA Framework) отбирает треугольники и пиксели с невероятной скоростью. Каждый представленный вами треугольник должен быть преобразован (через ваш вершинный шейдер). Затем он отбрасывает те, которые приземляются за пределы экрана. Затем он заполняет оставшиеся треугольники, отбрасывая пиксели, которые находятся за пределами экрана. Оставшиеся пиксели затем выводятся в задний буфер (через ваш пиксельный шейдер).

(Когда я говорю «тогда» - он фактически делает все это в массивно параллельном конвейере.)

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


Так что, как правило, геометрия за кадром обходится совсем не дорого.

Стоимость - особенно в контексте рисования «объектов» (обычно 3D-объектов) - фактически заключается в том, чтобы в первую очередь передать эти объекты в графический процессор . Отправьте слишком много объектов, и вы достигнете своего предела партии (вы получаете несколько тысяч * партий за кадр).

Я рекомендую прочитать этот ответ и эту связанную слайд-колоду для более подробного описания партий.

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


Теперь - ваш вопрос о 2D XNA - так что, вероятно, вы используете SpriteBatch. Это немного по-другому.

Это не ошибка, что она называется "Sprite Batch ". То, что он делает, - это берет спрайты, которые вы рисуете, и прилагает все усилия, чтобы передать эти спрайты в графический процессор как можно меньшим количеством пакетов , объединяя их вместе.

Но SpriteBatch будет вынужден запустить новый пакет, если:

  • Вы рисуете больше спрайтов, чем может поместиться в одной партии (2048 спрайтов в XNA 4)
  • Вы изменяете текстуру (вот почему есть опция сортировки по текстуре)

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

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

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


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

Эндрю Рассел
источник
5
+1 За упоминание о том, чтобы не делать отбор только ради этого, но когда это требуется для производительности.
Уилл Маркуиллер
12
+1 за то, что наконец сказал мне, что спрайт-листы действительно имеют причину для существования, кроме как для удобства программиста / дизайнера
Bill
3
+1 за отличное объяснение, я многому научился из твоего ответа.
Джесси Эмонд
1
Ссылка на PDF-файл "Batch, Batch, Batch" не работает. Вот обновленный: ce.u-sys.org/Veranstaltungen/…
Мартон,
13

Согласно сообщению на форумах MSDN, фреймворк XNA не делает выборку усеченного конуса:

Фреймворк XNA не сделает для вас никакого выбора frustum - он не может быть, потому что не имеет ни малейшего понятия, где что-то на самом деле закончится. Все преобразования выполняются на графическом процессоре и могут быть пользовательскими шейдерами.

http://xboxforums.create.msdn.com/forums/p/22763/121897.aspx

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

Nate
источник
6
Особенно, если у вас есть карта прокрутки (вы сказали, что это 2D, так что это может быть актуально). Это просто пустая трата, если вы рисуете большие разделы, которые не нужны. Это не очень сложно, и вы можете увидеть какое-то улучшение.
Майкл Коулман
1

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

Профиль XNA HiDef (не Reach) имеет класс OcclusionQuery, который используется для выполнения Occlusion Culling. Occlusion Culling удаляет те четырехугольники из области просмотра, которые скрыты от просмотра другими квадраторами.

Что-то еще, что вы должны рассмотреть, является ведение как поколения, так и тесселяции по отдельности.

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

Джейсон Кумбс
источник