Оптимизация: почему время важнее полигонов

В этом материале преподаватель курса OutBlock и левел-дизайнер VOID Interactive Денис Куандыков объясняет, как устроена оптимизация, и почему количество полигонов тут — не ключевой фактор.

Оптимизация: почему время важнее полигонов
242242

в ассасине вон 60к отрисовок в пещере, при этом с нагрузкой на железки вроде все более менее ок, это как так вообще?) https://youtu.be/aBWenAJ0cGU?t=441

1

В целом не все дроколлы имеют одинаковую стоимость на cpu, многое зависит от того, что делается между ними (меняется шейдер, обновляются буфферы, меняется рендер стейт, например, включается альфа-блендинг). Ну т.е. допустим есть 5 дроколлов на 2 шейдерах (s1 s2) и 3 материалах (m1,m2,m3). Пусть материалы m1 и m2  используют шейдер s1, а третий материал s2. Тогда можно дроколлы делать так:

set s1->set m1->draw1
set s2->set m3->draw2
set s1->set m2->draw3
set s2->set m3->draw4
set s1->set m1->draw5

А можно так:
set s1->set m1->draw1, draw5
set m2->draw3
set s2->set m3->draw4

Тут суммарно будет меньше изменений состояний gpu и работать это будет быстрее.(вероятно, см ниже). Батчинг в движках он не только про инстансинг геометрии, он и про такое уменьшение количества смены стейтов. Это разумеется не жесткие батчи, обычно это все решается специально сортировкой поданных на рендер объектов. При этом надо учитывать, что батчить "по жесткому" может быть не выгодно по многим причинам (early-z, например, из-за которого лучше сначала рисовать ближние объекты, и это не позволяет батчить далекие от камеры объекты с ближними). В целом тут вопрос конкретного проекта и конкретных замеров, в разных ситуациях разные решения оказываются быстрее. Это один из вариантов, которым можно повысить число дроколлов, не уменьшая время отрисовки.

Второй - использование новых апи (вулкан, дх12, апи пс4 и т.п.) Там основная фишка в том, что достаточно большая часть работы по подготовке дроколлов переносится из кода драйвера в код приложения, что позволяет не делать кучу синхронизаций, т.к. драйверу обычно неизвестно, когда приложение захочет нарисовать какой-то объект, поэтому какие-то ресурсы могут быть недоступны на момент дроколла (например, не быть в видеопамяти), это все надо проверить и исправить, если что не так (например, перетащить текстуру в память карточки или дождаться, пока освободится какая-то текстура, используемая в других отрисовках). На проверку всего этого уходит много времени, причем это почти нереально делать параллельно на нескольких ядрах. С новыми апи предполагается, что движок сам знает, в каком состоянии ресурсы, где они в памяти расположены и т.п., и драйверу не нужно делать дополнительной работы (на самом деле нужно, но сильно меньше, чем раньше). Это сильно увеличивает число доступных дроколлов. В ассасине новые апи начали использоваться очень рано, на пк это одна из первых серий, где движок по настоящему использовал новые апи и был разработан вокруг них (рендер anvil был почти полностью переписан при разработке ac:unity), поэтому там большие количества дроколлов поддержаны изначально и не настолько влияют на перформанс, как у других.

22

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

Очень "легки" дравколл, сам по себе DC это лишь команда - все зависит от того как устроен у них сам рендер пайплайн.
Тем не менее последние ассасины очень требовательны к CPU.

На практике, драйвер достаточно умён, чтобы не слать команду сразу на GPU. Он может делать собственный батчинг на низком уровне.