Defold. Уменьшаем размер билда. Texture Profiles.

В прошлой статье я рассказал, как уменьшить билд, выбросив ненужные модули из бинарника. Скажем так, что выигрыш для размера билда там не самый большой, но для маленькой игры важен и он.

А в этот раз я рассмотрю другую фичу движка Texture Profiles.

Defold Texture Profiles

Texture profiles — конфигурационный файл, содержащий настройки для всех графических ассетов, используемых в игре.  В нем прописывается формат текстур, степени и методы сжатия, необходимость создания mipmaps и другие опции.Процесс создания файла достаточно простой и описан в официальном мануале (главное, не забыть подключить его в game.project), поэтому давайте пропустим эту чать и перейдем к опциям, которые он предоставляет.

  • Path Settings — возможность создать профиль для каждой отдельного атласа или папки с атласами в проекте. 
  • Profiles — здесь выбирается профиль для дальнейшей настройки.
  • Platforms — возможность задать индивидуальные настройки профиля для каждой из платформ. os-id-generic — это опция для всех платформ, поэтому будьте осторожны натсраивая ее.
  • Formats — формат текстуры для данного профиля. Это могут быть как стандартные RGB или RGBA текстуры, так и различные спецефические для платформ ETC1 или PVRTC.

  • Compression — степнь сжатия от FAST (быстрая, но с низким качеством) до BEST (медленная, но с высоким качеством).
  • Type — тип сжатия стандартный (Zlib), WebP или WebP lossy, которые я рассмотрю ниже.
  • Mipmaps — включение и отключение генерации mipmaps.
  • Max Texture Size — максимально допустимый размер текстуры. Если здесь выставлено любое значение отличное от нуля, то текстуры больше этого размера будут сжиматься до указанного значения.
  • Premultiply alpha — подробнее о том, что это за опция в этой статье.

Про все эти опции подробно и с рекомендациями написал на форуме технический художник Кинг: Mattias Hedberg. Очень рекомендую для ознакомления. А мы перейдем к интересующей нас теме.

Сжимаем билд

Теперь, когда мы разобрались с тем, какие инструменты у нас есть, давайте посмотрим, что мы можем с этим сделать для того, чтобы ужать билд.

Если вы не знаете зачем нужны mipmaps в 2d проекте или вас, как и меня,  не устраивает качество, которое получается при их использовании (пока в Defold нельзя контролировать уровень mipmap), то можете их отключить. Это сэкономит вам место и нервы при борьбе с «мутной картинкой».

Если у вас очень большой проект с большим количством графики, то обязательно разбейте ваши ассеты на несколько профилей. Всегда можно выделить те ассеты, которые можно подвергнуть сжатию и оно останется незаметным для глаза. Если у вас есть спрайты без прозрачности, то соберите их в отдельный атлас и используйте для них RGB текстуру вместо RGBA.

Форматы текстур

Давайте коротко рассмотрим форматы текстур, которые можно использовать для нашей задачи (полное описание есть в документации):

  • PVRTC и ETC — если у вас есть возможность использовать эти форматы в вашем проекте, несмотря на все их ограничения, то это стоит делать. Так вы сэкономите оперативную память и место на диске. Кроме того, увеличите скорость загрузки игры. Но эти форматы изначально с потерями качества и другими недостатками (и хаками по их обходу), поэтому, лично у меня, этот формат нигде не используется.
  • …16bpp — можно использовать16-ти битные текстуры вместо 32-х битных. Это тоже сэкономит вам место и оперативную память, но не везде это возможно. Для такого формата отлично подойдут текстуры без градиентов, в противном случае зернистости не избежать.
  • обычные текстуры — ну, тут все понятно, полноцветность и единственные недостаток — это большой объем на диске и в оперативной памяти. Если вопрос с оперативной памятью решается грамотной загрузкой и выгрузкой объектов и сцен с нужными текстурами, то с местом на диске все сложнее, или проще в случае с Defold, потому как в нем есть интересные форматы сжатия.

Сжатие текстур

Подробнее о сжатии в документации, а вот мой краткий обзор:

  • Zlib или Default — обычное сжатие, ничего особенного. Используется по умолчанию, если ничего другого не выбирать.
  • WebP — а вот это уже интереснее. Это тип сжатия разработанный компанией Google и в Defold он поддерживается для всех типов текстур (даже для PVRTC и ETA). Его использование уменьшает размер текстуры на диске примерно на 30% и не влияет на качество изображения. Распаковка происходит в отдельном потоке, поэтому игра (ui поток) не зависает, но есть и недостатки, об этом ниже.
  • WebP-lossy — то же самое, но уже с потерями качества. Его нельзя использовать для PVRTC и ETA, т.к. эти форматы уже с потерями. Позволяет добиться еще меньшего размера текстур.

Разработчики на форуме давали примерно такое соотношения размера текстур в разных форматах с разным сжатием:

RGBA + ZLib — 86Mb
RGBA + WebP (lossless) — 32Mb
RGBA + WebP (lossy best) — 23Mb
PVRTC + ZLib — 21Mb
PVRTC + WebP — 15Mb
RGBA + WebP (lossy hi) — 13Mb

Недостатки

Ну и конечно недостатки сжатия, куда же без них. Я сделал синтетический тест, который не претендует на абсолютную истину, т.к. есть множество факторов, которые влияют на результат, но примерную картину составить он помогает. Вот краткий результат (полная версия с исходном кодом) :

10  полностью заполненных 2048×2048 атласов.

Размеры билда:
WebP: Default:
ios 11.2 Mb 14.1 Mb
android 9.7Mb 12.7 Mb
game.arcd — файл игровых ресурсов с текстурами 7.2 Mb 10.2 Mb
Скорость загрузки:
1я загрузка
Последующие загрузки
Xiaomi Redmi Note 4 WebP 1.62 сек 2.73 сек
Xiaomi Redmi Note 4 Default 0.55 сек 0.95 сек
iPad 4 WebP 3.2 сек 3.38 сек
iPad 4 Default 1.3 сек 1.3 сек

Вот и основной минус WebP экономия в 30% размера привела к увеличению скорости загрузки примерно в 3 раза. Звучит страшно, но на примере с 10ю текстурами 2048×2048 это 3Mb выигрыша и 1-2 секунды замедления скорости загрузки. Нужно оно вам или нет, смотрите сами. А лучше перемерить конкретно на вашем проекте, т.к. результат может отличаться.

Итог по текстурам и сжатию

В моих проектах, так сложилось, что качество картинки всегда на первом месте, да и сами изображения не очень подходят для сжатия. Поэтому в 99% случаев мы используем TEXTURE_FORMAT_RGBA. Но иногда есть вещи, где можно использовать другой формат и подобрать приемлемое качество.

Мы стараемся распределять загрузку таким образом, чтобы в память грузились только те текстуры, что нужны в данный момент, поэтому мы без проблем используем WebP сжатие без потерь, не боясь проиграть в скорости загрузки, либо WEBP_LOSSY с компрессией High там, где не критично или не заметны потери.

Самый надежный вариант проверить сжатие — это дать художнику 2 билда с и без сжатия и спросить об отличиях. Если художник разницу не нашел или  посчитал ее незначительной — такое сжатие можно оставлять. ^___^

На что еще обратить внимание

Кроме текстур и размера бинарника, следует обратить внимание на следующие пункты:

  • используйте slice-9 текстуры в GUI там, где это возможно (подробнее о том, что это);
  • не забывайте сконвертировать wav звуки в ogg с оптимальными для вашего проекта настройками;
  • если вы храните много данных в lua файлах (таблицы локализации, данные уровней и т.д.), то убедитесь, что эти файлы не подключается в проект через require. Так к примеру *.lua файл размером 1Mb превратиться почти в 2Mb *.luac файл после компиляции;
  • используйте опцию Compress Archive в настройках проекта;
  • при сборке бандла используйте опцию Generate build report, включение этой опции создаст отчет в формате html рядом с билдом и позволит проанализировать, что именно занимает больше всего места.

На этом, пожалуй, можно закрыть тему размера билда. Как всегда, буду рад любым вопросам и коментариям.