Как всем известно, жизнь разработчика мобильных игр непроста.
Ему предстоит найти свой путь на очень узкой тропе.
С одной стороны, это требования геймдизайнеров, уверенно устремляющихся в бесконечность.
Больше функционала, более красивая графика, больше эффектов, больше анимации, больше звуков.
С другой стороны, ресурсы мобильного устройства ограничены.
И в первую очередь, как правило, заканчивается оперативная память.
Например, iPad 2 имеет всего 512 МБ оперативной памяти.
Однако приложению доступно только около 275 МБ.
Когда занимаемая приложением память приближается к этому пределу, операционная система отправит так называемое «Память предупреждение» — мягко, но настойчиво предложит освободить память.
А если лимит все же будет превышен, операционная система остановит приложение.
Пользователь подумает, что у вас игра вылетела, и побежит писать гневное письмо в поддержку.
Основной потребитель памяти — это, конечно же, графика.
В этой статье мы попытаемся рассказать о немного сложном, но эффективном методе, который используется для уменьшения памяти, занимаемой текстурами, а также для увеличения скорости рендеринга.
Текстуры и атласы
Как всем известно, рисовать текстуры непосредственно из исходных файлов — плохая идея.Вместо этого они упакованы в текстурированные атласы.
Текстурный атлас — это большое изображение, созданное путем склеивания мелких текстур.
Это экономит память и, что более важно, уменьшает количество пакетов при рендеринге.
Есть два видео, которые наглядно демонстрируют, чем атлас хорош, а отдельные текстуры плохи: один раз И два .
Таким образом, задача упаковки текстурного атласа обычно сводится к следующему: взять прямоугольники разных размеров (исходные текстуры) и максимально плотно упаковать их в один большой прямоугольник, или, чаще, квадрат. Мы не на Олимпиаде и идеальная упаковка нам не нужна, но написать алгоритм, плотно упаковывающий текстуры за разумное время, совсем не сложно.
Мы уже довольно давно используем этот алгоритм, который генерирует для нас текстурные атласы.
Что-то вроде этого:
Как легко заметить, свободного места в нем довольно много и текстуры очень хочется упаковать поплотнее.
Причина неэффективной упаковки в том, что многие текстуры содержат достаточно большие прозрачные области.
Поэтому однажды мы решили попробовать отказаться от привычной прямоугольной упаковки и сделать то, что со временем стало известно как «полигональный атлас».
Для этого нужно решить 2 задачи: 1. Для каждой исходной текстуры нам нужно найти набор треугольников, содержащий все непрозрачные пиксели.
Затем, если мы нарисуем все эти треугольники, на экране появится исходная текстура.
Есть важное ограничение — треугольников не должно быть слишком много, иначе рендеринг будет очень медленным.
Таким образом, необходим компромисс между количеством треугольников и занимаемой ими площадью.
Поэтому сначала был написан алгоритм со множеством параметров для тонкой настройки, и только потом, проводя эксперименты на реальных текстурах, мы подбирали эти параметры.
2. Полученные фигуры сложной формы (те же многоугольники) нужно как можно плотнее упаковать в атлас.
Здесь использован один из вариантов алгоритма рой пчел , который путем многочисленных попыток с помощью генератора случайных чисел пытался найти достаточно плотный вариант упаковки.
Здесь требовался компромисс другого рода – между качеством упаковки и временем, затрачиваемым на упаковку.
Пройдя довольно долгий путь и попытавшись упаковать тестовый атлас примерно 100 000 раз, мы наконец добились результата:
Как видите, упаковка действительно намного плотнее.
В зависимости от текстур усиление может составлять до 1/4 их площади.
Также можно сгенерировать отладочную версию атласа, в которой можно увидеть разбивку текстур на треугольники.
Помимо самого атласа генерируется его описание, в котором указываются названия исходных текстур и координаты получившихся треугольников.
При использовании полигональных атласов процесс рисования, с одной стороны, ускоряется, с другой - замедляется.
Он ускоряется, потому что общая рисуемая область стала меньше, и, следовательно, значение перерисовки также стало меньше.
А тормозит это потому, что если раньше любая текстура рисовалась всего двумя треугольниками, то теперь, как видно на приведенном примере, их гораздо больше.
В целом, при разумных настройках упаковщика атласов, мы не заметили каких-либо серьезных изменений в скорости системы рендеринга.
Есть еще одна проблема, с которой мы столкнулись при переходе на новые атласы.
Часто необходимо нарисовать не всю текстуру, а только ее часть.
Например, если вам нужно сделать постепенное появление объекта на экране или какого-то индикатора прогресса.
При использовании обычных атласов проблема легко решается корректировкой уф-координат. В случае с полигональными атласами все становится сложнее.
Давайте посмотрим на пример.
На картинке синим цветом выделена часть текстуры, которую необходимо нарисовать:
Необходимый:
- Исключить из рисования треугольники, не попадающие в нарисованную часть текстуры.
- Найдите пересечения новой границы текстуры с исходными треугольниками.
Результат может больше не быть треугольником, и его, возможно, придется разделить на два новых треугольника.
Кроме того, такой алгоритм может работать не очень быстро.
Есть и более сложные случаи.
Например, круговой прогресс или какое-то искажение текстур.
Поэтому оказалось, что некоторые текстуры проще упаковать в обычные атласы или не упаковывать вообще, чтобы не усложнять процесс рендеринга.
Некоторые технические подробности.
Время упаковки полигонального атласа во многом зависит от настройки качества упаковки.
Поскольку атласы необходимо перестраивать при каждом изменении набора текстур, делать это приходится довольно часто.
Поэтому у нас обычно включен режим «минимальная плотность, максимальная скорость».
В этом режиме 8 атласов размером 2048x2048 упаковываются примерно за 5 минут. В общих чертах процесс упаковки выглядит так:
- текстуры разделены на треугольники;
- текстуры отсортированы по убыванию высоты;
- предварительная упаковка текстур.
Все текстуры выбраны по порядку и для каждой найдено свободное место в атласе;
- Было предпринято несколько попыток более плотной переупаковки текстур.
Количество попыток зависит от настроек качества;
- Если оригинальную упаковку удалось улучшить, то в атлас добавляются дополнительные текстуры.
При попытке улучшить качество время упаковки очень сильно увеличивается - до нескольких часов на 1 атлас - и выигрыш может составить 2-3 дополнительно упакованные текстуры.
В играх мы используем собственный движок.
Чтобы перейти на полигональные атласы, нам пришлось его немного доработать.
К счастью, у нас уже была абстрактная рисуемая сущность — класс Drawable:
Теги: #Playrix #игры #текстуры #разработка #атласы #Оптимизация клиента #Разработка мобильных приложений #Разработка игр #Обработка изображенийclass Drawable {
-
Недорогой Хостинг Quickbooks В Облаке
19 Oct, 24 -
В Китае Пропало 10 Тысяч Доменов
19 Oct, 24 -
Интересные Международные События В Январе
19 Oct, 24