Избавление от артефактов сжатия PVRTC текстур

 

Избавление от артефактов сжатия PVRTC текстур 

 

Проблематика


При разработке мобильных игр многие сталкиваются с необходимостью уменьшения занимаемой оперативной памяти или размера дистрибутива. Чаще всего самые тяжеловесные ассеты в проекте это текстуры. Несжатая текстура размером 1024х1024 занимает в районе 4 Мб. А в сцене обычно таких текстур не мало. И если мы хотим, чтобы сцены нашей игры загружались быстрее и не занимали слишком много оперативной памяти, мы вынуждены подвергать текстуры компрессии. В unity3d для мобильных устройств существует несколько типов сжатия. Думаю, описанный здесь подход для повышения качества результата компрессии текстур будет справедлив для всех алгоритмов, но рассматривать мы будем на примере PVRTC. У него есть один большой плюс, и один большой минус. Размер текстур уменьшается в восемь раз, но при этом появляются ужасные артефакты, особенно на прозрачных текстурах. Данная тема призвана помочь в борьбе с последними.

Алгоритм


Суть алгоритма заключается в постобработке текстур перед сжатием. Для этого нам понадобится графический редактор, умеющий работать со слоями. Я использовал Adobe Photoshop. Рассмотрим алгоритм подробно:

1) Открываем текстуру в фотошопе, и создаем новый слой поверх существующего.
2) Заливаем его средним оттенком серого.





3) Далее на этот слой накладываем шум с настройками как на рисунке:



4) Выставляем режим наложения «Soft Light» и прозрачность от 30 до 50 процентов таким образом, чтобы шум не очень бросался в глаза, но все же был виден.



5) Сохраняем и импортируем текстуру.



Если текстура полупрозрачная – то просто выделите пиксели с исходного слоя, инвертируйте выделение и удалите пиксели из зашумленного слоя.

После импорта осталось только указать сжатие RGBA Compressed PVRTC 4bit. Очень советую во вкладках импортера iOs и Android поставить галочку Override и указать Best в Compression Quality. Если ваша текстура будет использована для GUI, снимите галочку Generate Mip Maps. Это избавит вас от эффекта «замыления», если элемент UI будет расположен достаточно далеко от камеры.

Результаты



Как видим, все артефакты благополучно ушли. Обратите внимание на зеленый камень и шестеренку вокруг таймера вверху.

Заключение


До использования этого нехитрого способа мне приходилось оставлять текстуры для GUI несжатыми, из-за чего приложение зачастую занимало в памяти очень много места. Но с данным подходом получается сжать почти все текстуры для интерфейсов. Кроме очень мелких деталей, которые все же приходится выносить на отдельные атласы и оставлять в RGBA TrueColor. Но экономия памяти колоссальная. Данный подход был успешно применен в совместном проекте Heyworks Unity Studio и iFree Innovations – DragonIt. Весь предоставленный в статье графический материал сделан на основе текстур из этого проекта.