Ад визуализации 1.1 — Решения и заключение

Original author: Simon Trümpler
  • Translation
Ад визуализации 1.1:
Теперь самое интересное! Здесь я представлю вам некоторые решения, которые я нашел во время своего исследования. Надеюсь, они дадут вам общее представление о том, как оптимизировать игровые ресурсы с точки зрения процесса визуализации.

1. Сортировка


Для начала, вы можете упорядочить все ваши команды (например, по Render State'у) перед заполнением буфера команд. Эта операция уменьшит количество необходимых изменений Render State'а до минимума, так как вы можете обработать все полигональные сетки одного и того же вида.



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

2. Batching


Когда вы сортируете полигональные сетки, вы как бы складываете их вместе в кучки группируя по виду. Следующий шаг — попросить GPU визуализировать каждую кучку за раз. В этом вся суть Batching'а:
Batching — это группировка нескольких полигональных сеток до вызова методов API для их визуализации. Это делается из-за того, что для визуализации одной большой полигональной сетки требуется меньше времени, чем для множества маленьких. [a36]
Итак, вместо вызова одного Draw Call'а на полигональную сетку (которая имеет тот же Render State)…



… вы объединяете полигональные сетки (с одинаковым Render State'ом) и отображаете их за один Draw Call. Это действительно интересная тема, потому что вы можете визуализировать разные сетки (камень, стул или меч) одновременно, пока они используют одинаковый Render State (по существу, это значит, что они используют одинаковые настройки материала).



Важно помнить, что объединение полигональных сеток происходит в оперативной памяти (RAM) и только потом новая большая сетка передается в память графической карты (VRAM). Это требует времени! Поэтому Batching хорошо подходит для статических объектов (камни, дома...), которые объединяются один раз и хранятся в памяти долгое время. Конечно, вы можете объединять и динамические объекты, например, такие как лазерные выстрелы в космической игре. Но так как они постоянно движутся, вам придется каждый кадр создавать сетку «облака выстрелов» и передавать ее в память GPU!

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

Более подходящее решение для обработки динамических объектов — инстанцирование.

3. Инстанцирование


Инстанцировать — значит отправить только одну полигональную сетку (например, выстрел лазера) вместо нескольких, и дать GPU дублировать ее несколько раз. Рисовать один и тот же объект в одной позиции с одинаковым вращением или анимацией — довольно скучно. Поэтому вы можете передать поток дополнительных данных, таких как матрица трансформации, для визуализации дубликатов в разных позициях (и разных позах).
Типичные атрибуты для копии — матрица трансформации «модели к миру», цвет копии и плеер анимации вместе с костями. [a37]
Не бейте меня сильно, но как я понимаю, этот поток данных — просто список в RAM, к которому GPU имеет доступ.

Итого, требуется только один Draw Call на тип полигональной сетки! В сравнении с Batching'ом, разница заключается в том, что все экземпляры выглядят одинаково (так как копируется одна и та же сетка), тогда как объединенная сетка может состоять из нескольких разных при условии, что они используют одинаковые параметры Render State'а.



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

4. Шейдер для мультиматериалов


Шейдер может иметь доступ к нескольким текстурам и поэтому можно использовать не только одну диффузную/нормальную/отражающую текстуру, а две, например. Естественно, это значит, что можно объединить два материала в одном шейдере. Материалы смешиваются друг с другом, а степень смешения определяется контролирующей текстурой. Конечно, это требует дополнительных затрат от GPU, так как смешивание — дорогая операция, но она уменьшает количество Draw Call'ов за счет того, что больше не приходится «рвать» полигональную сетку на части (см. «4. Полигональные сетки и мультиматериалы»).

Прочитать подробнее об этом вы можете здесь.
Документация говорит, что большее количество Draw Call'ов все еще лучше, чем эта дорогая техника. Тем не менее, она показалась мне очень интересной и, если вам нужны хорошие числа для статистики, вы можете утверждать, что «слоеные» материалы уменьшают количество Draw Call'ов (пускай это ничего не говорит о производительности… но тссссс!).

5. «Кожные» полигональные сетки


Помните выше говорилось о сетке лазерного выстрела? Я говорил, что эта полигональная сетка должна обновляться каждый кадр, так как выстрелы постоянно движутся. Объединять их воедино и отправлять результат каждый кадр — довольно дорого. Интересный подход к решению этой проблемы заключается в автоматическом добавлении кости каждому выстрелу и передаче информации как о «коже». Таким образом, вы можете использовать одну большую полигональную сетку, которая может оставаться в памяти, а вы будете обновлять каждый кадр только информацию о костях. Конечно, если будет сделан новый объект-выстрел или будет уничтожен старый, вам придется пересоздать полигональную сетку. Но это звучит как действительно интересная идея, как мне кажется.

Прочитать подробнее об этом вы можете здесь.
Не стесняйтесь присылать мне больше ссылок о необычных решениях для уменьшения количества Draw Call'ов!
Почти все! Теперь у вас есть определенное понимание о том, что можно сделать для визуализации игровых ресурсов чуть быстрее. Не беспокойтесь, следующая книга будет короткой.

Конец

Ад визуализации 1.1:
Здесь я кратко изложу, что мы уже изучили:

Избегайте маленьких полигональных сеток


Проверьте необходимость маленьких сеток или есть возможность объединить несколько маленьких в одну большую. Поговорите с графическим программистом, чтобы получить информацию о «золотой середине» в количестве полигонов (максимум треугольников, при визуализации которых не происходит потеря производительности). Возможно вы захотите добавить несколько треугольников, чтобы сгладить углы. Также следует следить за мультиматериалами. Если вы собрали одну большую полигональную сетку, но с 5 назначенными материалами, то большая сетка будет разбита для визуализации, а это значит, что у вас так и осталось 5 маленьких сеток. Может быть вам поможет атлас текстур?

Избегайте слишком большого количества материалов


Говоря о материалах, думайте об управлении ими. Совместное использование материалов между игровыми ресурсами может оказаться возможным, если вы спланируете это перед созданием ресурса. Большие атласы текстур могут вам помочь.

Инструменты отладки


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

Спрашивайте кодера


Как вы видите, эта тема очень техническая и сильно зависит от контекста (железо, движок, драйвер, перспективы игры...). Поэтому, конечно, это хорошая идея — поговорить с программистом о том, как следует настраивать игровые ресурсы. Или просто ждите, если потеря производительности происходит из-за ваших ресурсов, то программисты найдут вас и будут тыкать, пока не оптимизируете все, что делали. :)
Вы знаете подсказки, которые мне следует сюда добавить? Дайте мне знать!
Ого, вы прочитали до сюда? Вы — сумасшедшие! Большое спасибо! Расскажите, что вы об этом думаете. Я надеюсь, вы узнали для себя что-то новое. :)

Конец


[a36] Technical Breakdown – Assassins Creed II
[a37] NVidia GPU Gems 2

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 3

    0
    Расскажите, что вы об этом думаете.

    Я думаю, что это неплохое пособие для художника в геймдеве. Потому что очень важно, чтобы художник/моделлер понимал как там все внутри крутится
      +1
      Неудачные вы статьи для перевода выбрали. Мусолят одно и то же, объеденяйте геометрию в группы, реже переключайте стейты. очень и очень скудно.
      Есть же хорошие годные презентации от самих железячников с подробным объяснением и сравнением функций в разных API, а так же стоимости переключений разных стейтов!
      www.slideshare.net/CassEveritt/beyond-porting?related=1
      www.slideshare.net/CassEveritt/approaching-zero-driver-overhead

      glDraw..BaseVertex, glDraw..BaseInstance к изучению в первую очередь. glDraw..Indirect и indirect буфера во вторую очередь. Как софтварный костыль — multidraw. В DX аналогичные фукцнии. Ни слова об текстурных атласах:
      www.blackpawn.com/texts/lightmaps/default.html
      и текстурных массивах. Ни слова о bindless. Ни слова о юниформ буферах и ни слова о BindRange. Ни слова о оптимизации заполнения динамических буферов. Скудно для серии из 4-х статей.

      И вот еще с заделом на будущее, NV готовится выкатить уберфичу, убийцу всяких там мантлов:
      www.slideshare.net/tlorach/opengl-nvidia-commandlistapproaching-zerodriveroverhead
        0
        Да, статьи рассчитаны на самых новичков. Мне понравились поясняющие видео.
        Я и сам не так давно начал изучать все эти технологии real-time render'ов.
        Спасибо за ссылки!

      Only users with full accounts can post comments. Log in, please.