У веб-переглядачі найкраще використовувати один величезний лист аркуша чи багато (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
├────┼────┼───┼────┼──────────┼─────┤
│8192│8193│...│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.