Ад візуалізації 1.1 - Рішення і висновок

Ад візуалізації 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

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.