Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Оптимізація Графічного Процесора
Вступ
Попит на нові графічні можливості та прогрес майже гарантує, що ви зіткнетеся з вузькими місцями в графіці. Деякі з них можуть бути на стороні центрального процесора, наприклад, під час обчислень всередині рушія Godot для підготовки об'єктів до рендерингу. Вузькі місця також можуть виникати на центральному процесорі в графічному драйвері, який сортує інструкції для передачі на графічний процесор, і в процесі передачі цих інструкцій. І, нарешті, вузькі місця виникають і на самому графічному процесорі.
Вузькі місця в рендерингу залежать від апаратного забезпечення. Зокрема, мобільні графічні процесори можуть не справлятися зі сценами, які легко відтворюються на настільних.
Розуміння та дослідження вузьких місць графічного процесора дещо відрізняється від ситуації на центральному процесорі. Це пов'язано з тим, що часто ви можете змінити продуктивність лише опосередковано, змінюючи інструкції, які ви даєте графічному процесору. Крім того, може бути складніше провести вимірювання. У багатьох випадках єдиний спосіб виміряти продуктивність - це дослідити зміни у часі, витраченому на малювання кожного кадру.
Виклики малювання, зміни стану та API
Примітка
Наступний розділ не стосується кінцевих користувачів, але корисний для надання довідкової інформації, яка буде використана в наступних розділах.
Godot надсилає інструкції графічному процесору через графічний API (Vulkan, OpenGL, OpenGL ES або WebGL). Зв’язок і діяльність драйвера можуть бути досить дорогими, особливо в OpenGL, OpenGL ES і WebGL. Якщо ми можемо надати ці інструкції у спосіб, який віддають перевагу драйверу та графічному процесору, ми можемо значно підвищити продуктивність.
Майже кожна команда API в OpenGL вимагає певної перевірки, щоб переконатися, що графічний процесор знаходиться в правильному стані. Навіть, здавалося б, прості команди можуть призвести до шквалу закулісної роботи. Тому мета полягає в тому, щоб звести ці команди до мінімуму і згрупувати схожі об'єкти якомога більше, щоб їх можна було вимальовувати разом або з мінімальною кількістю змін стану.
2D пакетування
У 2D витрати на обробку кожного елемента окремо можуть бути непомірно високими — на екрані їх легко можуть бути тисячі. Саме тому використовується 2D пакетування. Кілька подібних елементів групуються та відображаються пакетно за допомогою одного виклику малювання, а не для кожного елемента окремо. Крім того, це означає, що зміни стану, матеріалу та текстури можна звести до мінімуму.
3D пакетування
У 3D ми все ще прагнемо звести до мінімуму виклики малювання та зміни стану. Однак об’єднати декілька об’єктів в один виклик малювання може бути складніше. Тривимірні сітки, як правило, складаються з сотень або тисяч трикутників, а поєднання великих сіток у режимі реального часу є надзвичайно дорогим. Витрати на їх об’єднання швидко перевищують будь-які вигоди, оскільки кількість трикутників зростає на кожну сітку. Набагато кращою альтернативою є з’єднання сіток завчасно (статичні сітки по відношенню одна до одної). Це можуть зробити художники або програмно в Godot за допомогою доповнення.
Також існує певна вартість групового об'єднання об'єктів у 3D. Кілька об'єктів, відрендерених як один, не можна вирізати окремо. Ціле місто, яке знаходиться поза екраном, все одно буде відрендерено, якщо його об'єднати з однією травинкою, яка знаходиться на екрані. Таким чином, завжди слід враховувати розташування об'єктів та їх відсіювання, намагаючись групувати 3D-об'єкти. Незважаючи на це, переваги об'єднання статичних об'єктів часто переважують інші міркування, особливо для великої кількості віддалених або низькополігональних об'єктів.
Для отримання додаткової інформації про специфічні 3D-оптимізації див. Оптимізація продуктивності 3D.
Повторне використання шейдерів і матеріалів
Рендерер Godot дещо відрізняється від того, що існує. Він створений для мінімізації змін стану GPU, наскільки це можливо. StandardMaterial3D добре справляється з повторним використанням матеріалів, які потребують подібних шейдерів. Якщо використовуються власні шейдери, переконайтеся, що ви використовуєте їх якомога частіше. Пріоритети Godot:
Повторне використання матеріалів: Чим менше різних матеріалів у сцені, тим швидшим буде рендеринг. Якщо у сцені велика кількість об'єктів (сотні або тисячі), спробуйте використовувати матеріали повторно. У гіршому випадку, використовуйте атласи, щоб зменшити кількість текстурних змін.
Повторне використання шейдерів: якщо матеріали не можна використати повторно, принаймні спробуйте повторно використати шейдери. Примітка: шейдери автоматично повторно використовуються між StandardMaterial3D, які мають однакову конфігурацію (функції, які вмикаються або вимикаються за допомогою прапорця), навіть якщо вони мають різні параметри.
Якщо сцена містить, наприклад, 20 000 об’єктів із 20 000 різних матеріалів кожен, візуалізація буде повільною. Якщо та сама сцена містить 20 000 об’єктів, але використовує лише 100 матеріалів, рендеринг буде набагато швидшим.
Вартість пікселя в порівнянні з вартістю вершини
Можливо, ви чули, що чим менша кількість полігонів у моделі, тим швидше вона рендериться. Це насправді відносно і залежить від багатьох факторів.
На сучасному ПК та консолі вартість вершини є низькою. Спочатку графічні процесори рендерили лише трикутники. Це означало, що кожен кадр:
Всі вершини повинні були бути перетворені процесором (включаючи відсікання).
Всі вершини потрібно було відправити в пам'ять графічного процесора з основної оперативної пам'яті.
Зараз усе це виконується всередині GPU, що значно підвищує продуктивність. 3D-художники зазвичай мають неправильне уявлення про продуктивність polycount, оскільки програмне забезпечення для 3D-моделювання (таке як Blender, 3ds Max тощо) має зберігати геометрію в пам’яті ЦП для її редагування, що знижує фактичну продуктивність. Ігрові движки більше покладаються на графічний процесор, тому вони можуть відтворювати багато трикутників набагато ефективніше.
На мобільних пристроях все інакше. Графічні процесори для ПК та консолей - це монстри грубої сили, які можуть тягнути з електромережі стільки електроенергії, скільки їм потрібно. Мобільні графічні процесори обмежені крихітним акумулятором, тому вони повинні бути набагато енергоефективнішими.
Щоб бути більш ефективними, мобільні графічні процесори намагаються уникати перемальовування. Перемальовування виникає, коли один і той самий піксель на екрані рендериться більше одного разу. Уявіть собі місто з кількома будівлями. Графічні процесори не знають, які є видимі, а які приховані, доки не намалюють їх. Наприклад, може бути намальований будинок, а потім інший будинок перед ним (це означає, що рендеринг відбувся двічі для одного і того ж пікселя). Графічні процесори ПК зазвичай не дуже переймаються цим і просто додають більше піксельних процесорів до апаратного забезпечення, щоб збільшити продуктивність (що також збільшує енергоспоживання).
На мобільних пристроях не можна використовувати більше енергії, тому вони використовують техніку, яка називається плитковий рендеринг, який ділить екран на сітку. Кожна комірка зберігає список намальованих до неї трикутників і сортує їх за глибиною, щоб мінімізувати перемальовування. Ця техніка покращує продуктивність і зменшує енергоспоживання, але негативно впливає на продуктивність вершин. Як наслідок, для малювання обробляється менша кількість вершин і трикутників.
Крім того, плитковий рендеринг не справляється з малими об'єктами зі складною геометрією в межах невеликої частини екрану. Це змушує мобільні графічні процесори сильно навантажувати одну плитку екрану, що значно знижує продуктивність, оскільки всі інші комірки повинні чекати на її завершення, перш ніж відобразити кадр.
Підсумовуючи, не турбуйтеся про кількість вершин на мобільному, але уникайте концентрації вершин у малих частинах екрану. Якщо персонаж, NPC, транспортний засіб тощо знаходиться далеко (тобто виглядає крихітним), використовуйте модель з меншим рівнем деталізації (LOD). Навіть на настільних графічних процесорах бажано уникати трикутників менших за розмір пікселя на екрані.
Зверніть увагу на додаткову обробку вершин, необхідну при використанні:
Скінінг (скелетної анімації)
Морфінг (ключі форми)
Об’єкти, освітлені вершинами (поширені на мобільних пристроях)
Піксельні/фрагментні шейдери та швидкість заповнення
На відміну від обробки вершин, витрати на затінення фрагментів (на піксель) різко зросли протягом багатьох років. Роздільна здатність екрану зросла: площа екрана 4K становить 8 294 400 пікселів проти 307 200 для старого екрана 640 × 480 VGA. Це в 27 разів більше площі! Також вибухнула складність фрагментних шейдерів. Фізична візуалізація вимагає складних обчислень для кожного фрагмента.
Перевірити, чи не обмежена частота заповнення проекту, дуже просто. Вимкніть V-Sync, щоб запобігти обмеженню кількості кадрів на секунду, а потім порівняйте кількість кадрів на секунду при роботі з великим вікном і при роботі з дуже маленьким вікном. Якщо ви використовуєте тіні, вам також може бути корисно зменшити розмір карти тіней. Зазвичай, ви побачите, що FPS значно зростає при використанні маленького вікна, що вказує на те, що у вас певною мірою обмежена швидкість заповнення. З іншого боку, якщо збільшення FPS незначне або взагалі відсутнє, це означає, що вузьке місце лежить деінде.
You can increase performance in a fill rate-limited project by reducing the amount of work the GPU has to do. You can do this by simplifying the shader (perhaps turn off expensive options if you are using a StandardMaterial3D), or reducing the number and size of textures used. Also, when using shaded particles, consider forcing vertex shading in their material to decrease the shading cost.
Дивись також
На підтримуваному апаратному забезпеченні Затінення зі змінною швидкістю можна використовувати для зменшення витрат на обробку затінення без впливу на чіткість країв на кінцевому зображенні.
Якщо ви орієнтуєтесь на мобільні пристрої, використовуйте найпростіші шейдери, які ви можете собі дозволити.
Читання текстур
Іншим фактором у фрагментних шейдерах є вартість зчитування текстур. Зчитування текстур є дорогою операцією, особливо коли зчитується декілька текстур в одному фрагментному шейдері. Також враховуйте, що фільтрація може ще більше сповільнити її (трилінійна фільтрація між міпмапами та усереднення). Зчитування текстур також дорого коштує з точки зору використання енергії, що є великою проблемою на мобільних пристроях.
Якщо ви використовуєте сторонні шейдери або пишете власні, намагайтеся використовувати алгоритми, які вимагають якомога менше зчитувань текстури.
Стиснення текстури
За замовчуванням Godot стискає текстури 3D-моделей при імпорті, використовуючи стиснення відеопам'яті (VRAM). Стиснення відеопам'яті не таке ефективне при зберіганні, як PNG або JPG, але значно підвищує продуктивність під час малювання достатньо великих текстур.
Це пов'язано з тим, що основною метою стиснення текстур є зменшення пропускної здатності між пам'яттю та графічним процесором.
У 3D, форма об'єктів більше залежить від геометрії, ніж від текстури, тому стиснення, як правило, непомітне. У 2D стиснення більше залежить від форм всередині текстур, тому артефакти, що виникають в результаті 2D стиснення, більш помітні.
Попередження: більшість пристроїв Android не підтримують стиснення текстур з прозорістю (тільки непрозорі), тому майте це на увазі.
Примітка
Навіть у 3D для "піксельних" текстур слід вимкнути стиснення VRAM, оскільки воно негативно вплине на їхній зовнішній вигляд, не покращуючи при цьому продуктивність через низьку роздільну здатність.
Постобробка та тіні
Ефекти постобробки та тіні також можуть бути дорогими з точки зору активності затінення фрагментів. Завжди перевіряйте їхній вплив на різному обладнанні.
Зменшення розміру карти тіней може підвищити продуктивність, як з точки зору запису, так і з точки зору читання карти тіней. Крім того, найкращий спосіб покращити продуктивність тіней - це вимкнути тіні для якомога більшої кількості джерел світла та об'єктів. Для менших або віддалених OmniLights/SpotLights часто можна вимкнути тіні, що матиме лише невеликий візуальний вплив.
Прозорість і змішування
Прозорі об'єкти створюють особливі проблеми для ефективності рендерингу. Непрозорі об'єкти (особливо у 3D) можна візуалізувати у будь-якому порядку, а Z-буфер гарантує, що затінюватимуться лише передні частини об'єктів. З прозорими або змішаними об'єктами все інакше. У більшості випадків вони не можуть покладатися на Z-буфер і мають бути відрендереними у "порядку художника" (тобто ззаду наперед), щоб виглядати коректно.
Прозорі об'єкти також особливо погано впливають на заповнюваність, оскільки кожен об'єкт повинен бути намальований, навіть якщо згода зверху будуть намальовані інші прозорі об'єкти.
Непрозорі об'єкти можуть цього не робити. Зазвичай вони можуть скористатися перевагами Z-буфера, записуючи спочатку в Z-буфер, а потім застосовуючи фрагментний шейдер лише до "переможного" фрагмента, тобто об'єкта, який знаходиться спереду на певному пікселі.
Прозорість особливо дорого коштує там, де кілька прозорих об'єктів накладаються один на одного. Зазвичай краще використовувати прозорі області якомога меншого розміру, щоб мінімізувати ці вимоги до заповнення, особливо на мобільних пристроях, де заповнення є дуже дорогим. Дійсно, у багатьох ситуаціях рендеринг складнішої непрозорої геометрії може виявитися швидшим, ніж використання прозорості для "обману".
Мультиплатформні поради
Якщо ви плануєте випустити гру на декількох платформах, тестуйте заздалегідь і тестуйте часто на всіх платформах, особливо на мобільних. Розробляючи гру для десктопів, намагатися перенести її на мобільні пристрої в останню хвилину - це рецепт катастрофи.
Загалом, ви повинні створити свою гру для найменшого спільного знаменника, а потім додати додаткові вдосконалення для більш потужних платформ. Наприклад, ви можете використовувати метод відтворення сумісності як для настільних комп’ютерів, так і для мобільних платформ, де ви націлюєтеся на обидві.
Мобільні/плиткові рендерери
Як описано вище, графічні процесори на мобільних пристроях працюють кардинально інакше, ніж графічні процесори на десктопах. Більшість мобільних пристроїв використовують плитковий рендеринг. Плиткові рендери розбивають екран на плитки звичайного розміру, які поміщаються у надшвидку кеш-пам'ять, що зменшує кількість операцій читання/запису до основної пам'яті.
Однак є й деякі недоліки. Плитковий рендеринг може зробити певні техніки набагато складнішими та дорожчими у виконанні. Плитки, які покладаються на результати рендерингу в різних плитках або на збережені результати попередніх операцій, можуть працювати дуже повільно. Будьте дуже уважні під час тестування продуктивності шейдерів, текстур області перегляду та постобробки.