- PVSM.RU - https://www.pvsm.ru -
В этой статье я хочу поделиться своим опытом разработки мобильной игры, поскольку я Windows Phone разработчик, я буду рассказывать про свой опыт применительно к этой системе.
Если Вы уже занимались разработкой мобильных игр, то основное зло не в нехватке ресурсов CPU/GPU, а в нехватке памяти. Именно о памяти нужно думать в мобильной разработке в первую очередь. В Windows Phone 7 ограничение было в 100мб, в Window Phone 8 стало получше, но не сильно:
Тип лимита | Тип приложения | Телефоны с маленьким количеством памяти | 1- Гб телефоны | 2-Гб телефоны |
Default | XNA или native | 150 MB | 150 MB | 150 MB |
Default | XAML/.NET excluding XNA | 150 MB | 300 MB | 300 MB |
Higher | All app types | 180 MB | 380 MB | 570 MB |
И если Вы разрабатываете игру, в которой довольно большое количество спрайтов (уложенных, конечно же, в атласы) — то вы рано или поздно задумаетесь о количестве этих самых атласов и сжатии текстур.
Стандартный атлас, с которым работают все более или менее уважающие себя устройства — это 2048х2048 пикселей. Что в несжатом виде (32 bits per pixel) будет занимать аж 2*2*4 = 16 Мб памяти. Тогда на выручку приходят форматы сжатия текстур, в нашем случае это DXT сжатие.
Сжатые текстуры не только требуют значительно меньше памяти видеокарты, но и вообще отображаются быстрее, чем несжатые текстуры, за счет снижения требований к пропускной способности. Но некоторые качества изображения могут быть потеряны из-за сжатия. Тем не менее, снижение объема памяти позволяет увеличить разрешение текстур, которые будут использоваться, что действительно может дать существенный выигрыш в качестве.
Dxt компрессия уже реализована в .XNA Frameworke, а также в Monogame.
Для наглядности, возьмем 256 изображений размером 128х128 пикселей, один текстурный атлас из этих текстур размером 2048*2048, и сожмем этот атлас.
Ходят слухи о том, что быстрее подгружаются текстуры размер, которых кратен степени двойки, для эксперимента изменим немного оригинальную текстуру, срезав один пиксель, доведя ей размер 2048*2047.
Чтобы показать действенность описанных методов сделаем контрольные замеры. Проводить их будем на телефоне Nokia Lumia 800. Для большей точности сделаем для каждого метода 10 замеров.
Сведем получившиеся результаты в таблицу 1 и подведем итог.
Таблица 1. Скорость загрузки изображений.
256 текстур по 128*128 | 1 dxt 2048*2048 | 1 origin 2048*2048 | 1 origin 2048*2047 | |
1 | 00:00:00.6460000 | 00:00:00.0330000 | 00:00:00.1510000 | 00:00:00.1200000 |
2 | 00:00:00.6440000 | 00:00:00.0330000 | 00:00:00.1510000 | 00:00:00.1180000 |
3 | 00:00:00.6470000 | 00:00:00.0410000 | 00:00:00.1870000 | 00:00:00.1570000 |
4 | 00:00:00.6400000 | 00:00:00.0330000 | 00:00:00.1490000 | 00:00:00.1190000 |
5 | 00:00:00.6420000 | 00:00:00.0330000 | 00:00:00.1500000 | 00:00:00.120000 |
6 | 00:00:00.6340000 | 00:00:00.0470000 | 00:00:00.1320000 | 00:00:00.161000 |
7 | 00:00:00.6340000 | 00:00:00.0500000 | 00:00:00.1590000 | 00:00:00.179000 |
8 | 00:00:00.6300000 | 00:00:00.0500000 | 00:00:00.1580000 | 00:00:00.179000 |
9 | 00:00:00.6330000 | 00:00:00.0480000 | 00:00:00.1580000 | 00:00:00.179000 |
10 | 00:00:00.6210000 | 00:00:00.0470000 | 00:00:00.1650000 | 00:00:00.1820000 |
Среднее | 00:00:00.6371000 | 00:00:00.0412000 | 00:00:00.1558000 | 00:00:00.1514000 |
Для наглядности график зависимости различных методов загрузки от времени (рис. 1.)
Рисунок 1. График зависимости различных методов загрузки от времени.
Таблица 2. Размеры изображений
Методы | Размеры, Мб | |
1 | Размер 256 текстур по 128*128 | 16 |
2 | Размер текстуры 2048*2048 без сжатия | 16 |
3 | Размер текстуры 2048*2048 с сжатием | 4 |
Как мы видим из представленных опытов Dxt сжатие очень эффективно. Рассмотрим его более подробно.
DXT сжатия (также иногда известный как сжатие S3 ) на самом деле очень простое. Вот как это работает:
Эта простая схема, оказывается, работает удивительно хорошо для многих реальных изображений мира.
Есть пять вариантов DXT сжатия:
DXT1 использует 64 бита на блоке 4x4. По сравнению с 32-битной несжатой текстурой, это 8x кратная степень сжатия. DXT2-5 использует 128 бит в блоке 4x4, которая дает 4х кратная степень сжатия.
А теперь плохая новость: DXT сжатие – это сжатие с потерями. Иногда они могут быть очень большими. На самом деле это работает очень хорошо для некоторых изображений и совсем не подходит для других.
Итак, когда Вы хотите использовать Dxt компрессию скажем в XNA, когда Вы устанавливаете свойство текстуры Texture формат, параметр DxtCompressed, Content Pipeline автоматически выбирает между DXT1 и DXT5, в зависимости от того, имеет ли ваша текстура альфа-канал. Если она не содержит альфа-канал или содержит однородный альфа-канал будет использовать DXT1, чтобы получить наилучшую степень сжатия, но если текстура содержит дробные значения альфа-канала, он выберет DXT5 вместо этого.
Рассмотрим более подробно каждый из способов сжатия:
DXT1 формат предназначен для декомпрессии в реальном времени аппаратными средствами на видеокарте во время рендеринга. DXT1 является форматом сжатия с потерями, с фиксированным коэффициентом сжатия 8:1. DXT1 сжатие является одной из форм кодирования блока усечениями (BTC), где изображение разбивается на непересекающиеся блоки, и пикселей в каждом блоке квантуются на ограниченное число значений. Значения цвета пикселей в блоке 4x4 пиксель аппроксимируются с равноудаленных точек на линии, проходящей через цветовое пространство RGB. Эта линия определяется двумя конечными точками, и для каждого пикселя в блоке 4x4 2-битный индекс хранится в одном из равноудаленных точек на линии. Концы линии, проходящей через цветовое пространство, кодируются в 16-битный формат 5:6:5 RGB и одна или две промежуточные точки генерируется за счет интерполяции. Формат позволяет хранить 1-битный альфа-канал, путем переключения на другой режим, основанный на порядке конечных точек, где создается только одна промежуточная точка и один вывод дополнительного цвета указывает, что он черный и полностью прозрачный.
Посмотрим на рисунок 2 представленный ниже:
Левое изображение является оригиналом. Правое иллюстрирует сжатие в формате DXT1.
Рисунок 2. Пример Dxt1 сжатия.
Визуально сжатое изображение не отличается от оригинала, что делает результаты сжатия приемлемыми для большинства пользователей. Сжатие, однако, значительно уменьшает размер текстуры.
В данном случае с 256 КБ до 32 КБ.
Однако все не так радужно с этой текстурой (рисунок 3):
Рисунок 3. Пример Dxt1 сжатия.
Основной проблемой является появление шума внутри текста, a также видны отчетливые полосы на фоне градиента.
Рисунок 4. Шумы внутри текста.
На рисунке 5 показано, как сжатие влияет на цвет. Слева Вы видите 16 оттенков красного, от чистого красного до чистого черного. Справа Вы видите четыре цвета, которые получились в результате DXT сжатия, из этих 16 оттенков.
Рисунок 5. Влияние сжатия на цвет.
Рисунок 6 показывает, что происходит, когда разные цвета не находятся на одной линии в цветовом пространстве. В этом случае были использованы все крайности палитры RGB (красный, зеленый и синий). Очевидно, в результате интерполированные цвета не совпадают с оригиналами. Обычно в области пикселей 4x4 не такой широкий выбор цветов, но это показывает, что текстуры с различными цветами страдают больше.
Рисунок 6. Влияние сжатия на цвет.
DXT1 сжатия обычно хорошо работает для шумных текстур и не так хорошо для чистых изображений, а также градиентов. Хитрость заключается в том, чтобы использовать его везде, где это возможно и не использовать его только на тех текстурах, где артефакты сжатия слишком нежелательны.
DXT5 формат, отличается от DXT3 формата, тем что он хранит информацию об альфа канале, подобно тому как хранить информацию о цвете.
Для информации об альфа-канале он использует палитру подобную той, как храниться цифровая информация. Эта палитра содержит минимальное и максимальное значение альфа-канала. Различают два варианта с 6 и 4 опорными точками.
6 других значений альфа интерполируются между этим минимумом и максимумом. Таким образом, это позволяет более постепенные изменения значения альфа.
Второй вариант делает интерполяцию только для 4 других значений альфа-канала между минимальной и максимальной величиной, но также добавляет альфа-значения 0 и 1 (для полностью прозрачными и не прозрачными). Для некоторых текстур это может дать лучшие результаты.
Рисунок 7. Пример Dxt5 сжатия.
Как видим, края не очень хорошо обрабатываются в некоторых частях.
Рисунок 8. Рванные края при использовании Dxt5 сжатия.
Размер текстуры при этом уменьшился с 256 КБ до 64 КБ.
Потери качества на реальных изображениях не столь значительны и ими можно для большинства изображений пренебречь.
Использование Dxt сжатия позволяет:
В своем проекте, после создания текстурного атласа, я получаю на выходе .jpg/.png/.bmp и описание атласа в .xml/.txt/.json. Поскольку я использую XNА/Monogame для сжатия в .xnb я использую XNA 4.0 Content Compiler [1] в целом это очень понятное и простое решение, только для использования Dxt сжатия необходимо дописать в ContentBuilder’e при создании buildProject еще одно свойство:
buildProject.SetProperty(“XnaCompressContent“, “True”);
Источники:
S3 Texture Compression [2]
DXT compression explained [3]
DXT Compression Techniques [4]
Real-Time YCoCg-DXT Compression [5]
Автор: dampirik
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/xna/50937
Ссылки в тексте:
[1] XNA 4.0 Content Compiler: http://xnacontentcompiler.codeplex.com/
[2] S3 Texture Compression: http://en.wikipedia.org/wiki/S3_Texture_Compression
[3] DXT compression explained : http://www.fsdeveloper.com/wiki/index.php?title=DXT_compression_explained
[4] DXT Compression Techniques: http://www.sjbrown.co.uk/2006/01/19/dxt-compression-techniques/
[5] Real-Time YCoCg-DXT Compression: http://www.nvidia.com/object/real-time-ycocg-dxt-compression.html
[6] Источник: http://habrahabr.ru/post/206386/
Нажмите здесь для печати.