Оптимизируем мидкор: ПК-качество и челленджи с производительностью. Текстуры и анимация

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

Текстуры

В этом разделе хочется уделить внимание текстурным атласам и их компрессии. Начнем с того, что вообще такое текстурный атлас? Это метод оптимизации, при котором мы объединяем несколько текстур в одну картинку. К примеру, вот так выглядит текстурный атлас для целого города в игре Railroad Empire. 

Что это дает нам в плане оптимизации

  • Меньше обращений к памяти телефона.
  • Кратно меньший объем текстур на локацию, а значит и меньший размер билда
  • Повышение FPS
  • Снижение нагрева устройства

Как это работает

Чем больше объектов будут использовать один и тот же материал, тем проще будет  SRP-батчеру в темплейте URP сшить эти объекты в один Draw Call (вызов отрисовки). А чем меньше вызовов отрисовки и полигонжа, тем меньше греется и тормозит мобильное устройство.

В игре Railroad Empire целые города построены всего на одном материале и одной текстуре. 

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

1. Не стесняйтесь ужимать некоторые текстуры 4096×4096, 2048×2048 до 1024×1024, плюс включать кранч компрессию

В 95% случаев вы не увидите разницу (если только это не лайтмап на белом фоне), но профит будет колоссальный. 2K текстура без ужатия, как правило обходится нам в 20 МБ. Но, если ужать ее до 1024 и включить компрессию, мы получим объем не более 380-500 КБ. Это очень хорошо для оптимизации. 

Как правило, текстурки на моделях должны иметь приемлемый вид на разрешении 1024×1024. Если это не так, скорее всего модель нужно отправлять на доработку текселя. В Railroad Empire, в рамках оптимизации, у большинства текстур выставлено разрешение 1024×1024. Это доказывает, что, если правильно выставить тексель денсити и грамотно сделать маппинг, можно получить очень дорогую картинку. Конечно, при условии, что текстуры проработаны. 

Ваш исходник все равно должен быть минимум 2048×2048. Ужать 2К до 1К —  дело нескольких галочек, а вот превратить 1024×1024 в 2048×2048 уже не получится. А еще это всегда ваша страховка на случай нерационального маппинга или запроса на локально повышенную детализацию, когда без 2048×2048 не обойтись. 

2. По возможности не используйте карты нормалей (Normal Map)

Например, на одном из проектов, была задача сделать «рябь на воде» от солнца.  Одним из самых простых способов было пустить в шейдере две нормали в противоположных друг другу направлениях и получить искривления. Но такое решение обойдется в минус 6 FPS на средних девайсах. Мне видится, что такие вещи проще «зафейкать» масками.

В Railroad Empire на воде нет ни единой карты нормалей. Все имитируется масками, движущимися по флоумапе. Блики отсутствуют концептуально, но они тоже могут быть легко добавлены через маски.

3. Если нужно подчеркнуть «контуры» и добавить затемнения, используйте Ambient Occlusion

Мы обычно оставляем Ambient Occlusion в альфа-канале Albedo, на текстурный атлас города. Таким образом удается усилить читаемость контуров и деталей зданий, сделать их более контрастными, даже без использования пост-процессинга. Ambient Occlusion ложится по UV2 каналу, т.к. UV1 занят тайлом.

Помимо небольшой прибавки в весе за счет использования UV2, в шейдере происходит чтение второго пака UV. Конечно, де-факто это является доп. нагрузкой на CPU и GPU, но все же менее затратно, чем вторая текстура.

Анимация

1. Чистите анимацию от лишних ключей

Часто возникают ситуации, когда все ключи (position, rotation, scale) сохраняются на каждом фрейме. Это не совсем рациональное решение, т.к. ключ — это «данные», которые прописываются в FBX.

Срезание лишних ключей может убрать до 90% веса всей анимации. В Railroad Empire на некоторых картах есть паромы, которые за 5-10 минут проплывают всю локацию. Если не срезать лишние ключи, вес такой анимации может доходить до 10 МБ. 

Лайфак: Если вам все-таки необходимо проанимировать каждый параметр на каждый фрейм, никто не запрещает ускорить анимацию в 5-10 раз уложившись в 30 фреймов, а потом, замедлить ее в аниматор контроллере. 

2. Используйте «пустышки» (Dummy)

В производстве часто прибегают к реюзу (переиспользованию). Например, если заказчики через какое-то время просят добавить несколько паромов, проще и оптимальнее один раз проанимировать Dummy и привязывать к нему нужный Mesh, чем каждый раз делать одни и те же анимации для разных объектов. 

Заключение

Как я и говорил в начале прошлой части, универсального рецепта «крутой графики»‎ в мобильных играх не существует. Кто-то использует весь ресурс вычислительных мощностей на «честную физику», а кто-то делает акцент на реалистичную картинку. Получить и то и другое сразу можно только на флагманских устройствах, но это сильно ограничит круг игроков, которые смогут познакомиться с вашей игрой. Поэтому для  каждого отдельного проекта приходится придумывать кастомные решения и использовать различные маленькие хитрости. 

*****

Вернуться в блог