2D графіка - навіщо використовувати spritesheets?


62

Я бачив багато прикладів того, як візуалізувати спрайти з spritesheet, але я не зрозумів, чому це найпоширеніший спосіб поводження з спрайтами в 2d іграх.

Я почав із 2d спрайтового спрайту в декількох демонстраційних програмах, які я створив, розглядаючи кожен анімаційний кадр для будь-якого типу спрайту як власну текстуру - і ця колекція текстур зберігається у словнику. Це, здається, працює для мене і досить добре підходить для мого робочого процесу, оскільки я прагну робити анімацію у вигляді gif / mng файлів, а потім витягувати кадри до окремих png.

Чи є помітна перевага для продуктивності в зображенні з одного аркуша, а не з окремих текстур? З сучасним обладнанням, здатним малювати мільйони багатокутників на екрані сто разів в секунду, чи це має значення навіть для моїх 2d ігор, які мають справу з кількома десятками прямокутників 50x100px?

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

Я підозрюю, що є кілька дуже вагомих причин, як здається, більшість розробників ігор 2d використовує їх, я просто не розумію, чому.


Ні, це насправді не має великого значення для ваших 50 дивних спрайтів. Але що втратити?
Качка комуніста

Відповіді:


69

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

Також врахуйте, що розміри текстур зазвичай мають потужність 2. Отже, якщо у вас спрайт 50x100px, ви виділите текстури розміром 64x128px або в гіршому випадку 128x128px. Це просто витрачає графічну пам’ять. Краще упакуйте всі спрайти в 1024x1024px текстури, що дозволить спрайтам 20x10, і ви втратите лише 24 пікселі по горизонталі та вертикалі. Іноді навіть спрайти різного розміру поєднуються в один величезний спрайт-лист, щоб використовувати текстуру максимально ефективно.

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


1
Дякую, я не розглядав жоден із цих моментів - Ви приблизно знаєте, яка межа обмежується кількістю доступних текстур? Я ніколи не бачив цієї статистики, згадуваної в специфікаціях графіки - чи обмеження в основному дорівнює кількості графічної оперативної пам'яті?
Коламбо

Зазвичай лімітом буде пам'ять GPU, так. Я думав, що існують певні обмеження щодо кількості текстур на старих картах, але я не можу знайти посилання, яке підтверджує це.
bummzack

12
Навіть якщо кількість обмежень не обмежена, автобусний рух для переміщення безлічі маленьких зображень не настільки ефективний, як один (або кілька) великих переказів.
Мордахай

5
Хороші моменти, але найважливіший аспект - мінімізувати стояки на трубопроводі шляхом зменшення кількості зворотних дзвінків. GPU вважають за краще невелику кількість великих робочих місць, а не велику кількість маленьких робочих місць. Якщо розмістити всі свої спрайти до невеликої кількості великих аркушів, ви можете один раз встановити етап textue і одразу намалювати безліч колючок. Spritebatch робить це за вас. Якщо у вас є декілька спрайтів, обов'язково повідомте spritebatch, щоб сортувати за текстурою
Cubed2D

Додавання стиснення текстури перетворить будь-який неміцний простір на дуже маленький об'єм накладних витрат, поверх цього
Джо Плант

36

Я б сказав, що аргументом для використання буде можливість виводити кілька речей за один розіграш. Візьмемо для прикладу візуалізацію шрифту, без узагальнювального листа вам потрібно буде зробити кожен символ окремим текстурним свопом з подальшим розімкненням дзвінка. Закиньте їх у спрайтовий лист, і ви зможете виводити цілі речення за допомогою одного дзвінка малювання (різниці символів у вибраному шрифті, просто вказавши різні УФ-куточки для кутів). Це набагато ефективніший спосіб візуалізації, коли дуже багато реальних витрат на візуалізацію на багатьох платформах - це робити занадто багато викликів API.

Це також може допомогти заощадити місце, але це залежить від того, яку упаковку ви отримаєте в spritesheet.


2
+1 Торкається дзвінків під час розіграшу. (чогось я не бачив у прийнятій відповіді)
Майкл Коулман

11

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


2
Це, безумовно, все ще має значення. Графічне обладнання було оптимізоване для виштовхування тонн багатокутників для невеликої кількості детальних моделей (наприклад, персонажів), оскільки більшість ігор прагнуть у цьому напрямку. Результат полягає в тому, що вам потрібно просунути якомога більше багатокутників у кожному з кількох десятків розіграшів. Ігрові двигуни, які створюють великі сцени, як міста, часто поєднують декілька текстур в одну на ходу, щоб зменшити дзвінки на розіграші.
поштовх

Мені напевно цікаво, чи текстура u, v відображення у великій кількості тривимірного обладнання, а також бітові відблискуючі операції виграють від спрайтового аркуша.
Джо Плант

7

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

Крім того, я кодую в AS3, і кожен файл зображення вимагає окремої інструкції з вбудовування. Я вважаю за краще мати одне вбудовування цілого spritesheet, ніж 24 вбудовування для всіх кадрів, навіть якщо я використовую окремий клас ресурсів.


1
+1. Незважаючи на те, що ОП не використовує Flash, вбудовування або завантаження також є перевагою на користь спрайтів. Це також актуально, коли активи завантажуються з веб-сервера, де 1 запит віддається перевазі понад кілька сотень запитів (для кожного "кадру").
bummzack

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

7

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


5

Я не збираюся згадувати тут пам'ять / GPU, оскільки відповідей на це є досить.

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

І тоді ще чистіше (з організаційної точки зору) мати символу.png та neprija.png через characterwalk01 до символуalk10, потім karakterattack01 до karakterattack05, і це продовжується.


4

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

Один такий простий і швидкий обмін пам'яттю може бути схожим на наявність лише одного гігантського спрайта 4096x4096, який розрізається на кілька менших спрайтів, наполовину його ширину та / або висоту. (Існує аналогічна одновимірна техніка управління пам’яттю, але я забув назву.) Врешті-решт, слід виконати дефрагментацію.

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


3

Також не забудьте операції вводу / виводу, які можуть зберегти вас під час ініціалізації. Якщо ви завантажуєте з компакт-диска, кожен файл - це додатковий дзвінок вводу-виводу, і це може зайняти деякий час (сучасні жорсткі диски - це близько 15 мс на файл, компакт-диск може бути 50-100 мс?). Це може заощадити багато часу на ініціалізацію, оскільки потрібно отримати лише один файл. Він також дозволяє вашій ОС кешувати ці операції вводу / виводу, якщо ваша програма робить щось інше (наприклад, очікування GPU).


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

0

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

На мою думку це також простіше кодувати. У мене просто є масив об'єктів, таких як:

sheet = {
    img: (the actual image),
    rects: [
        {x:0, y:0, w:32, h:32},
        {x:32, y:0, w:32, h:32},
        {x:64, y:0, w:32, h:32}
    ]
};

sheets.push(sheet);

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.