Dxt стиснення в іграх, savepearlharbor

У цій статті я хочу поділитися своїм досвідом розробки мобільної гри, оскільки я Windows Phone розробник, я буду розповідати про свій досвід стосовно до цієї системи.

Пам'ять і текстури

Якщо Ви вже займалися розробкою мобільних ігор, то основне зло не в нестачі ресурсів CPU / GPU, а в нестачі пам'яті. Саме про пам'ять потрібно думати в мобільній розробці в першу чергу. У Windows Phone 7 обмеження було в 100мб, в Window Phone 8 стало трохи краще, але не сильно:

Таблиця 1. Швидкість завантаження зображень.

256 текстур по 128 * 128

1 origin 2048 * 2048

1 origin 2048 * 2047

Для наочності графік залежності різних методів завантаження від часу (рис. 1.)

Dxt стиснення в іграх, savepearlharbor

Малюнок 1. Графік залежності різних методів завантаження від часу.

Таблиця 2. Розміри зображень

Розмір 256 текстур по 128 * 128

Розмір текстури 2048 * 2048 без стиснення

Розмір текстури 2048 * 2048 з стисненням

Як ми бачимо з представлених дослідів Dxt стиснення дуже ефективно. Розглянемо його більш детально.
DXT стиснення (також іноді відомий як стиснення S3) насправді дуже просте. Ось як це працює:

  • Зображення ділиться на блоки 4х4
  • Для кожного блоку, знаходиться два найважливіших кольору
  • Утворені два кольори зберігаються в 16 бітах, в форматі RGB 5.6.5
  • Для кожного з 16 пікселів в блоці, зберігається 2 біта значення, яке вказує, як далеко він знаходиться між двома основними кольорами

Ця проста схема, виявляється, працює на диво добре для багатьох реальних зображень світу.

Є п'ять варіантів DXT стиснення:

  • DXT1 працює, як я описав вище, плюс деяка додаткова магія для кодування альфа-каналу
  • DXT3 колір кодується також, як і DXT1, а також зберігає 4 біта значення альфа-каналу в пікселі
  • DXT5 колір кодується також, як і DXT1, а також подібна схема використовується для кодування альфа-каналу
  • DXT2 і DXT4 були не дуже-добре продуманої спробою стандартизації і не чого ділового не вийшло. Ви повинні робити вигляд, що вони не існують

DXT1 використовує 64 біта на блоці 4 × 4. У порівнянні з 32-бітної незжатої текстурою, це 8x кратна ступінь стиснення. DXT2-5 використовує 128 біт в блоці 4 × 4, яка дає 4х кратна ступінь стиснення.

А тепер погана новина: DXT стиснення - це стиснення з втратами. Іноді вони можуть бути дуже великими. Насправді це працює дуже добре для деяких зображень і зовсім не підходить для інших.
Отже, коли Ви хочете використовувати Dxt компресію скажімо в XNA, коли Ви встановлюєте властивість текстури Texture формат, параметр DxtCompressed, Content Pipeline автоматично вибирає між DXT1 і DXT5, в залежності від того, чи має ваша текстура альфа-канал. Якщо вона не містить альфа-канал або містить однорідний альфа-канал буде використовувати DXT1, щоб отримати найкращу ступінь стиснення, але якщо текстура містить дробові значення альфа-каналу, він вибере DXT5 замість цього.

Розглянемо більш докладно кожен із способів стиснення:

Подивимося на малюнок 2 представлений нижче:
Ліве зображення є оригіналом. Праве ілюструє стиск в форматі DXT1.


Малюнок 2. Приклад Dxt1 стиснення.

Візуально стислий зображення не відрізняється від оригіналу, що робить результати стиснення прийнятними для більшості користувачів. Стиснення, однак, значно зменшує розмір текстури.
В даному випадку з 256 КБ до 32 КБ.

Однак все не так райдужно з цієї текстурою (малюнок 3):

Dxt стиснення в іграх, savepearlharbor

Малюнок 3. Приклад Dxt1 стиснення.

Основною проблемою є поява шуму всередині тексту, a також видно виразні смуги на тлі градієнта.


Малюнок 4. Шуми всередині тексту.

На малюнку 5 показано, як стиснення впливає на колір. Зліва Ви бачите 16 відтінків червоного, від чистого червоного до чистого чорного. Справа Ви бачите чотири кольори, які вийшли в результаті DXT стиснення, з цих 16 відтінків.

Dxt стиснення в іграх, savepearlharbor

Малюнок 5. Вплив стиснення на колір.

Малюнок 6 показує, що відбувається, коли різні кольори не знаходяться на одній лінії в колірному просторі. В цьому випадку були використані всі крайності палітри RGB (червоний, зелений і синій). Очевидно, в результаті інтерпольовані кольору не збігаються з оригіналами. Зазвичай в області пікселів 4 × 4 не такий широкий вибір кольорів, але це показує, що текстури з різними кольорами страждають більше.

Dxt стиснення в іграх, savepearlharbor

Малюнок 6. Вплив стиснення на колір.

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

DXT5 формат, відрізняється від DXT3 формату, тим що він зберігає інформацію про альфа каналі, подібно до того як зберігати інформацію про колір.
Для інформації про альфа-каналі він використовує палітру подібну до тієї, як зберігатися цифрова інформація. Ця палітра містить мінімальне і максимальне значення альфа-каналу. Розрізняють два варіанти з 6 і 4 опорними точками.
6 інших значень альфа інтерполюються між цим мінімумом і максимумом. Таким чином, це дозволяє більш поступові зміни значення альфа.
Другий варіант робить інтерполяцію тільки для 4 інших значень альфа-каналу між мінімальною і максимальною величиною, але також додає альфа-значення 0 і 1 (для повністю прозорими і непрозорими). Для деяких текстур це може дати кращі результати.

Dxt стиснення в іграх, savepearlharbor

Малюнок 7. Приклад Dxt5 стиснення.

Як бачимо, краю не дуже добре обробляються в деяких частинах.

Dxt стиснення в іграх, savepearlharbor

Малюнок 8. рвані краї при використанні Dxt5 стиснення.

Розмір текстури при цьому зменшився з 256 КБ до 64 КБ.
Втрати якості на реальних зображеннях не настільки значні і ними можна для більшості зображень знехтувати.
Використання Dxt стиснення дозволяє:

  • Зменшити розмір установчого пакета
  • Зменшити розмір використання оперативної пам'яті
  • Збільшити швидкість «відтворення» зображень

У своєму проекті, після створення текстурного атласу, я отримую на виході .jpg / .png / .bmp і опис атласу в .xml / .txt / .json. Оскільки я використовую XNА / Monogame для стиснення в .xnb я використовую XNA 4.0 Content Compiler в цілому це дуже зрозуміле і просте рішення, тільки для використання Dxt стиснення необхідно дописати в ContentBuilder'e при створенні buildProject ще одна властивість:

Схожі статті