У веб-переглядачі найкраще використовувати один величезний лист аркуша чи багато (10000) різних PNG?


33

Я створюю гру в jQuery, де я використовую близько 10000 плиток 32x32. До цих пір я використовував їх усі окремо (аркуш спрайтів). Середня карта використовує близько 2000 плиток (іноді повторно використовуються PNG, але всі окремі диви), а продуктивність коливається від стабільного (Chrome) до трохи млявого (Firefox). Кожна з цих дівок розміщується абсолютно за допомогою CSS. Їх не потрібно оновлювати кожен галочку, лише коли завантажується нова карта.

Чи було б краще для продуктивності використовувати методи spritesheet для divs з використанням CSS-фонового позиціонування, як це робить gameQuery?

Заздалегідь спасибі!


3
Де чорт вам потрібен 10 000 плиток для карти? Я пропоную вам не завантажувати / малювати всю карту на стороні користувача. Покажіть лише порцію, яку видно. Коли користувач рухається, завантажте наступний розділ. Те, як працює кожна 3D-графіка.
Діель

На середній карті використовується 2000 різних плиток, або всього 2000 всього плиток? Наскільки великі карти ви створюєте?
Нік Ларсен

Чи планували ви використовувати одне чи кілька великих зображень як фон та виконувати полігональне виявлення зіткнень для меж?
SAHornickel

Відповіді:


50

Моя пропозиція

Занадто багато маленьких PNG додадуть велику кількість накладних витрат на мережу (через розмір запитів HTTP, але також заголовок PNG, і, що ще важливіше, неможливість стиснутись ефективно). З іншого боку, один дуже великий PNG має недоліки, які потребує певного часу для завантаження, і йому потрібно постійно залишатися в пам'яті (40 мегабайт на 10000 плиток) у безперервному шматку пам'яті.

Я рекомендую середину: кілька PNG з розумним розміром, наприклад 1024 плитки розміром 32 × 32 . Може бути згруповано за темами (наприклад, PNG з лісовою плиткою, одна з гірською плиткою, інша з міською плиткою - я не знаю тему вашої гри, але ви розумієте).

Примітка про ефективність кешу

Через ефективність доступу до пам’яті ніколи не слід робити занадто широкі списки листів. Виблискуючі плитки із зображення розміром 128 × 8192 завжди будуть швидшими, ніж блимати від зображення 8192 × 128.

Уявіть, що ви хочете зафарбувати першу плитку на зображенні 8192 × 128. Для простоти припустимо, що 1 піксель - 1 байт. Перші два рядки пікселів викладені таким чином (комірки містять у байті їхнє число):

┌────┬────┬───┬────┬──────────┬─────┐
  0   1 │...│ 31    ....    8191 1st line of pixels: bytes 0 to 8191
├────┼────┼───┼────┼──────────┼─────┤
81928193│...│8223   ....   16383 2nd line of pixels: bytes 8192 to 16383
├────┼────┼───┼────┼──────────┼─────┤
 ..  .. │...│ ..    ....    ... 

Тож для того, щоб зафарбувати перший рядок першого заголовка, двигун браузера витягне байти 0до31 . Щоб зафарбувати другий рядок , він отримає байти 8192до8223 і так далі, поки не буде 32-й рядок, 253952в який253983 будуть отримані байти .

Загальна кількість оброблених байтів становитиме 32 × 32. Однак загальний діапазон пам'яті становить понад 253984 байт. У сучасному процесорі це означає 32 або 33 сховища кешу . На відміну від цього, якби зображення було 128 × 8192, діапазон пам’яті становив би лише 4000 байт, що означає не більше двох стійлів кешу.

Оскільки сьогоднішні процесори дуже швидкі, сховища кеш-пам'яті дуже дорогі і вивішують обчислення. Тож використання зображення 128 × 8192 замість зображення 8192 × 128 потенційно може бути в 8 разів швидшим, принаймні, теоретично. На практиці це буде залежати від того, як реалізується відблиск: можливо, що базовий двигун сам розбиває зображення на плитки, щоб зменшити проблему.

Це не легко пояснити правильно, і я не сподівався, що докладно розробити. Сподіваюся, це має сенс!


4
"Зауважте також, що через ефективність доступу до пам'яті, ви ніколи не повинні робити занадто широкі списки листів. Блискучі плитки із зображення розміром 128 × 8192 завжди будуть швидшими, ніж блимати від зображення 8192 × 128". - приємна цікавість, будь ласка, розкажіть, будь ласка? :)
Гримшоу

@DevilWithin: Я намагався пояснити проблему; дайте мені знати, якщо мені досить ясно!
sam hocevar

Ефективність кеш-пам'яті є захоплюючою. Чи є у вас якісь цифри на різницю, що це стосується частоти кадрів?
Григорій Евері-Вейр

Це проблема, схожа на реалізацію, але якщо API на зразок OpenGL таким чином діє на текстури, то, безумовно, важливо це врахувати, дякую :)
Grimshaw

2
@DevilWithin: те, що я написав, діє лише для процесора - GPU, будучи масово паралельним, має дуже різні налаштування кешу і зберігатиме текстури, використовуючи власний внутрішній формат, оптимізований для випадкового доступу. Це причина, чому в OpenGL рекомендується квадратна, потужність двох текстур, і я б дотримувався цього правила і для наборів плиток.
sam hocevar

5

Один величезний спрайшевий лист (ймовірно) забезпечить вам кращу продуктивність, просто тому, що одна з найбільших причин відставання - поїздка в зворотній бік від запиту браузера до сервера до браузера. 10000 HTTP-дзвінків забирає набагато довше, ніж 1 HTTP-дзвінок, який повертає файл на 10 000 більше.

Можливо, можна зменшити відставання, залежно від структури гри та HTML, який ви створюєте.

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