Чи повинен я використовувати спрайети, через чи незважаючи на велику кількість зображень?


13

Я розвиваю 2D гру, і у мене багато спрайтів. Я використовував 3D-анімації та моделі, щоб перетворити їх у 2D, щоб надати їм такий вигляд "Fallout" або "Diablo". Це також простіше, ніж малювати вручну, lol.

Мені вже довелося скоротити частоту кадрів до 15 кадрів в секунду, що було найнижчим, що я міг опустити, не змусивши їх поглянути на них. Однак це було сумно через те, як виглядали неймовірно гладкі 24 кадри.

У мене це дві причини:

1) Скоротіть місце на жорсткому диску. Чим менше зображень, тим меншою буде моя загальна гра.

2) Скорочення споживання оперативної пам'яті. Чим менше буде завантажувати зображень, тим більше шансів на те, щоб уникнути проблем, що обмежують обмеження оперативної пам'яті.

Однак, якби був спосіб стиснення зображень як у просторі на жорсткому диску, так і в оперативній пам’яті, я б це зробив. Я перевіряв це раніше, і більшість не отримує жодних змін якості при наданні з RGBA8888 на RGBA5555 і лише незначне враження при переході на RGBA4444 в моїй програмі TexturePacker. Я зараз цього не роблю, тому що, здається, SFML використовує однаковий об'єм пам'яті незалежно від типу .PNG-зображення. Я розглядав питання, як його по-різному завантажувати, але нічого не вдалося знайти з цього приводу.

Я багато читав про те, як обробляти 2D відеоігри. Консенсус надзвичайний: упакуйте свої спрайти в більшу текстуру для чудової продуктивності! Тому я запакував свої крихітні спрайти в набагато більшу спрайти, використовуючи TexturePacker.

Однак я планую мати 10-15 анімацій на персонажа, 5 напрямків для переміщення та 15-40 кадрів на анімацію (можливо, в середньому 24). З 15 анімаціями, 5 напрямками і в середньому 24 кадри на анімацію; Тобто 1800 індивідуальних кадрів на персонажа. Якщо вони упаковані в спрайт-аркуш, то замість цього всього 75 зображень. (Один спрайт лист на анімацію, за напрямом. 15 * 5)

Для одного величезного героя боса в грі я не можу використовувати таблицю спрайтів і мені потрібно запрограмувати спосіб просто завантажити одне зображення за один раз. Я не знаю, чи можу я це ще зробити для виступу.

Для персонажів я вже упаковую їх у спрайт-лист. Для одного персонажа, що ходить, це, здається, працює більшу частину часу, хоча іноді це затримується. Однак я пов'язую це зі своїм непродуманим кодом, який замінює текстури замість попереднього завантаження всіх текстур для цього символу.

Якби я попередньо завантажував текстури, це має сенс для спрайтових аркушів. Я б тільки уявив, що погана ідея попередньо завантажити 1800 крихітних зображень на кожного персонажа.

Однак, я думаю, передача їх у пам'ять і з пам'яті одна за одною була б надзвичайно швидкою, тому мені потрібно було б одночасно мати одне зображення в пам'яті. Чи не означає це, що в будь-який момент я мав би, щоб кожен символ споживав лише кілька КБ замість 45 + МБ?

Я думаю, що це призведе до вбивства моєї продуктивності, оскільки потокове передавання повинно бути неймовірно швидким (15 зображень, що надходять у пам'ять і виводяться за секунду), і хоча зображення будуть дуже маленькими - це може бути кращою ідеєю для завантаження символьних списків замість цього. Але мені все одно доведеться кодувати систему візуалізації, що нагадує потокове зображення, для мого більшого персонажа боса.

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


1. Ви не вказали обмеження оперативної пам'яті або жорсткого диска. Скільки символів потрібно мати швидкий доступ? 2. У тексті є кілька запитань, можливо, ви можете вирішити їх жирним шрифтом або навіть розділити їх на частини?
Кромстер

О, пробач. Не багато. Я б міг уявити, що максимальна кількість окремих символів на екрані в будь-який момент буде приблизно 40. Якби люди зробили крапку, щоб спробувати зірвати своїх клієнтів, то ... 130 - це абсолютний макс. Як правило, для типового максимуму потрібно бути лише 10, а абсолютний макс буде не більше <40. Все, що старше 40 років, було б надзвичайною, надзвичайною рідкістю, коли користувачі цілеспрямовано намагаються забитися символами без будь-якої причини, крім екрана екрана або для задоволення набивання персонажів. Все, що перевищує 10, є рідкісним, а щось близько 40 - надзвичайно, надзвичайно рідкісним.
Carter81

Гра - це лише 2D rpg для ПК (лише для ПК), однак я не хотів би виключати мобільну платформу, якщо це просто неможливо. Я думаю, що в мене є простор оперативної пам’яті, обмежений будь-якою оперативною пам’яттю на ПК користувача та VRAM користувача. Я дуже сумніваюся, що це буде дуже великий HDD. Просто споживання жорсткого диска завжди відповідає, що чим він менший, тим краще.
Carter81

Скільки UNIQUE символів потрібно мати на екрані?
Кромстер

Не більше 20. Все вище, що було б поруч із неможливим, якщо б вони не обдурили. Зазвичай 5-10.
Carter81

Відповіді:


16

У нас є подібний випадок з нашим RTS Remake. Усі одиниці та будинки - спрати. У нас є 18 000 спрайтів для одиниць, будинків і рельєфу, а також ще ~ 6 000 для командних кольорів (застосовується як маски). Довго розтягнуті ми також маємо близько 30 000 символів, що використовуються у шрифтах.

Тож основна причина атласів:

  • менша витрата оперативної пам’яті (за старих днів, коли ви завантажуєте NPOT в GPU, вона розтягувалася / підкладала її до POT, я читав, що все одно те саме з iOS та деякими рамками. Краще перегляньте спектр обладнання, на яке ви орієнтуєтесь)
  • менше текстурних перемикачів
  • швидше завантаження всього за менший розмір

Що не працювало для нас:

  • палітри текстур. Ця функція існувала лише у OpenGL 1.x 2.x і навіть тоді її виробники в основному відкидали. Однак якщо ви орієнтуєтесь на OpenGL + Shaders, ви можете зробити це в шейдерах, кодуючи себе просто чудово!
  • Текстури NPOT, у нас виникли проблеми з неправильними рамками та розмитими спрайтами, що в піксельному зображенні неприпустимо. Використання оперативної пам’яті теж було значно вище.

Тепер у нас все запаковано в кілька десятків атласів розміром 1024x1024 (сучасні графічні процесори підтримують ще більші розміри), і це добре працює, харчуючись лише ~ 300 Мб пам'яті, що цілком чудово для гри на ПК. Деякі оптимізації ми мали:

  • додати користувачеві можливість використовувати RGB5_A1 замість RGBA8 (тіні для шахів)
  • уникайте 8-бітної Альфи, коли це можливо, і використовуйте формат RGB5_A1
  • щільно упакуйте спрайтів в атласи (див. алгоритми упаковки у бін)
  • зберігати та завантажувати все в один фрагмент із жорсткого диска (файли ресурсів повинні генеруватися офлайн)
  • ви також можете спробувати апаратні формати стиснення (DXT, S3TC тощо)

Якщо ви серйозно подумаєте про перехід на мобільні пристрої, ви будете турбуватися про обмеження. Поки просто наведіть на роботу гру та залучайте гравців! ;)


Це було найкращим рішенням на сьогоднішній день! Мої спрайти навіть не виглядають різними в RGB5_A1 або RGBA4444, але це економить на пам'яті. Ваша пропозиція в чаті попередньо завантажити всі мої активи в оперативній пам’яті та VRAM ідеально. Ще більше, ви запропонували мати додаткові графічні рівні, такі як клієнт високої чіткості для тих, хто має оперативну пам’ять, або можливість зменшити частоту кадрів вдвічі і т. Д. Чудові пропозиції навколо, і саме те, що мені потрібно!
Carter81

5

У мене є тангенциально пов'язаний відповідь в тут , але загальна ідея полягає в тому, що, якщо ви завантажуєте і малювання текстур в різний час (ви не завантажуючи додаткові текстури в той час як ви будете рендеринга), тобто два місця , де то , що вам дійсно вплине на вашу ефективність:

Час завантаження:

Це момент, коли ви завантажуєте свої текстури в пам'ять. Весь обсяг даних , які ви відправляєте VRAM, що буде в основному визначати , як довго буде ваш час завантаження. Якщо текстури мають менші формати, як-от RGBA4444, це зробить це швидше. Однак, якщо ви не завантажуєте текстури у високі сотні мегабайт до VRAM, ви, ймовірно, не матимете тут вузького місця. Якщо це зробити, приємний екран завантаження може полегшити очікування.

Приєднання текстур до атласів матиме незначний ефект, оскільки вся кількість інформації, яку ви надсилаєте у VRAM, буде однаковою. Насправді, якщо ви атласуєте свої текстури, і вам доведеться залишати порожні пробіли у своїх атласах, то ви фактично будете надсилати більше даних у VRAM, і тому ця частина буде повільнішою!

Ефективність надання:

Після того, як всі ваші текстури знаходяться у VRAM, кількість наявних вами текстур не вплине на ефективність візуалізації. Є чотири елементи, які впливають на ефективність візуалізації:

  1. Зміни стану візуалізації : щоразу, коли ви змінюєте зображення, з якого ви хочете візуалізувати, це серйозно збільшуватиме час, необхідний для його відображення. Загалом, ви хочете мінімізувати кількість змін у стані, а можете зменшити кількість змін у стані, згрупувавши декілька зображень, які ви будете послідовно малювати, в атлас текстури.

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

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

  2. Здійснення дзвінків: загалом, можливо, ви захочете звозити дзвінки до мінімуму. Хорошим правилом є те, що якщо між двома дзвінками виклику не відбулося зміни стану візуалізації, ви можете приєднати їх до одного дзвінка. Для більш досконалого підвищення продуктивності можна використовувати, скажімо, 8 пробовідбірників текстур та групових дзвінків для малювання кожні 8 текстур, тому вам потрібно лише змінювати текстури кожні 8 текстур.

  3. Кількість трикутників: Насправді, чим більше ви намалюєте трикутників, тим довше буде потрібно їх малювати. Однак у сучасних комп’ютерах, а також у більшості двомірних ігор, ви будете дуже далекі від досягнення максимуму. Ви можете сміливо малювати сотні тисяч спрайтів на кадр і все одно отримувати шалено хороші рамки. Ви, ймовірно, будете більше пов'язані з процесором, якщо будете малювати надзвичайну кількість спрайтів, перш ніж у вас виникнуть проблеми з GPU.

  4. Налаштування API: Якщо ви все робите правильно, а у вас все ще дивно низькі рамки, перевірте параметри, за допомогою яких ви малюєте свої спрайти. Я не знаю SFML, але, наприклад, в Direct3D 9, створення вершинного буфера з D3DUSAGE_DYNAMICабо в, D3DPOOL_MANAGEDможе легко збільшити ваші часи візуалізації в десятки разів. Звичайно, використання vSync обмежує частоту кадрів зі швидкістю оновлення монітора. Також використання нерівних FVF може знизити продуктивність у деяких графічних процесорах. Це теж стосується Direct3D 9.

    У вашому випадку перегляньте документацію щодо API, який ви використовуєте.

Якщо у вас є лише низька до помірної кількості текстур (менше 1 ГБ) і ви малюєте низьку кількість спрайтів (менше мільйона на кадр), то перше, що я хотів би переглянути, - це зміни параметрів API, і потім зменшують кількість станів візуалізації та проводять дзвінки.


Якщо я не переймаюся часом завантаження, чи варто вважати, що, якщо у мене не закінчиться оперативна пам'ять або VRAM, я повинен заздалегідь завантажити все в пам'ять?
Carter81

Мене хвилює лише те, що я боюся занижувати RAM / VRAM. Я не знаю, чому, але кам'янить мене, що користувачі, які грають у мою гру, будуть виходити з ладу кожного разу, коли вони намагатимуться завантажити область, в якій є занадто багато унікальних спрайтів, або впадуть, коли занадто багато персонажів вийде на їх екран. Якщо я не помиляюся, і кожен окремий спрайт витрачає 96 КБ, то, якщо кожен унікальний символ має 15 анімацій, 5 напрямків і в середньому 24 кадри на анімацію - кожен повністю завантажений персонаж становить 173 Мб. На екрані може бути одразу 10, а може й більше.
Carter81

@KromStern: Якщо вам належить атлас, і вам доведеться залишати порожні місця (padding), то даних буде більше, а значить, час завантаження буде довшим. Зрозуміло, що причиною більш тривалого часу завантаження є порожній простір, і що загальний час завантаження пов'язаний із загальним обсягом даних, а не кількістю текстур. Я не бачу в цьому нічого оманливого, і я думаю, що людина, яка має достатньо знань, щоб зрозуміти оригінальне запитання, зможе приєднатися до крапок і зробити власні висновки для всіх випадків, коли текстури та атласи - PoT і nPoT.
Піжама Panda

1
@ Carter81: Вам потрібно вибрати цільову конфігурацію апаратури, наприклад "i5, 1 Гб оперативної пам'яті, NVidia GT260, 400mb hdd" і працювати над цим. Завжди знайдуться ПК, які слабші та мають менше оперативної пам’яті.
Кромстер

Очевидно, їм не потрібно всіх 15 анімацій в будь-який момент. Однак, що робити, якщо всі 10 унікальних персонажів одночасно переходять у «Бойовий режим», і тому потрібно 5 наборів анімацій (ходити, бігати, простоювати, не бою тощо), щоб їх замінити ще на 5 (бойова прогулянка, бойовий холостий, бойовий тощо)? Мені страшно міняти текстури, тому що коли я намагався робити це з SFML, це створювало помітне заморожування або паузу клієнта при переключенні текстурних атласів. Я не знаю, яке моє вузьке місце було б із різними стратегіями роботи з такою кількістю спрайтів.
Carter81
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.