Подготовка 2д арта для игр
Всём привет, меня зовут Григорий Дядиченко и я технический продюсер. Сегодня хочется обсудить подготовку 2д арта. Существует, скажем так, хороший тон в плане подготовки графических ассетов. Исходя из контекста технических ограничений и удобства дальнейшей работы. Больше речь про Unity3d конечно, но многие вещи работают везде одинаково и по сути меняются в нюансах. Если вам интересная данная тема, то добро пожаловать под кат!
![](https://webcf.waybackmachine.org/web/20211006162304/https://habrastorage.org/getpro/habr/upload_files/fbd/185/dfc/fbd185dfcde619c7b0bd3bf44c611e55.png)
Сразу оговорюсь, что в данной статье не будет какого-то ноу-хау решения. Скорее компиляция основных правил и техник, которыми надо пользоваться. Чтож, начнём!
Степень двойки
![](https://webcf.waybackmachine.org/web/20211006162304/https://habrastorage.org/getpro/habr/upload_files/195/0ff/de2/1950ffde27313ea4740b3c3126ddbfcb.jpg)
Одно из самых основных правил при подготовке арта - это текстуры размера степени двойки. Под степенью двойки я понимаю в данном случае размеры типа 128х128, 1024x512 и так далее. То есть каждая сторона текстуры должна в пикселях какой-то степенью 2.
Тут конечно лучше уточнять всегда у программистов сформируют ли они текстурный атлас автоматически, либо же данная текстура будет использоваться “как есть”. Потому что если текстура не кладётся в атлас то в идеале её размеры должны быть равны степени двойки. Для примера скажем Spine анимация, так как она уже является текстурным атласом.
Причин для этого достаточно много. Начиная от укладки текстур в видео-память и заканчивая тем, что из-за принципов работы современных алгоритмов сжатия текстур под разные устройства текстура 1023х1024 будет занимать больше места в приложении, нежели текстура 1024х1024, потому что движок не может её сжать.
Добавлять везде альфу тоже не хорошо. Если есть возможность запихать атлас все текстуры в атлас размера степени двойки без добавления альфа-канала - это самое лучшее. Но часто просто добавить альфы тоже неплохое решение, каким бы странным не казалось. Мы увеличиваем размеры текстуры, но при этом она становится меньше и работает лучше. Конечно же этим лучше не заниматься программистам, а учитывать именно художником, так как автоматическое “растягивание” и прочее часто приводит к артефактам в визуализации.
Текстурные атласы
![](https://webcf.waybackmachine.org/web/20211006162304/https://habrastorage.org/getpro/habr/upload_files/6dd/22f/e3e/6dd22fe3e6c3fb9522d7bb6321c19926.png)
Вторая вещь, которой важно пользоваться - это текстурные атласы. Текстурный атлас - это по своей сути супер текстура, в которой лежит множество отдельных текстур для ассетов. Они используются и в 3д, и в 2д графике.
В старые времена нужно было пользоваться специализированным софтом и плагинами для этого. Сейчас в Unity есть Sprite Packer, который работает из коробки. Он автоматически формирует текстурный атлас из спрайтов. Важно что из именно из спрайтов. Поэтому если для какого-то VFX текстура используется, как текстура - не забываем про степень двойки.
Что прикольно, Sprite Packer Unity собирает не просто атлас. Все спрайты пакуются в меши, что позволяет во-первых, укладывать текстуры компактнее, во-вторых, снизить альфа блендинг за счёт того, что не рисуется лишняя альфа. Главный нюанс который стоит учитывать - эта техника не работает с UI, так как там всегда всё рисуется с помощью квадратного меша. Поэтому пакуя атласы для UI спрайт пакером юнити нужно убирать галочки Allow Rotation и Tight Packing.
Основной плюс текстурных атласов в том, что гпу оптимальнее отрисовывает графику. Объекты рисуются в один Draw Call, текстуры лежат в видео памяти компактнее и их проще загружать на gpu в целом. Помимо этого художникам не нужно сильно париться за степень двойки в этом случае, так как все инструменты автоматически формируют правильный размер для оптимального сжатия.
Небольшим, я не скажу недостатком, а нюансом работы с атласами, надо думать как их паковать, чтобы максимум объектов используемых в атласе одновременно находились в кадре. Скажем у вас есть игра в которой между уровнями есть магазин, там есть некоторые товары типа оружия для персонажа. Но спрайты из магазина в игре не используются. Все их лучше сложить в отдельный атлас от игровых объектов. Так как допустим вы положили туда персонажа игры зачем-то, тогда на запуске уровня вместе с персонажем в видеопамять пойдут ещё и куча спрайтов, которые на уровне никогда не отобразятся. Тут опять-таки правило не железное, так как если ресурсов ГПУ у вас достаточно, а важнее снизить скажем вес сборки, то тогда конечно можно смешивать себе на здоровье, чтобы получить минимальное число текстур.
Боль программистов с градиентами
![](https://webcf.waybackmachine.org/web/20211006162304/https://habrastorage.org/getpro/habr/upload_files/a6a/da1/ae9/a6ada1ae99990e338a4f812813c22e33.jpg)
Если это необходимо по визуальному стилю и т.п., то это как бы не обсуждается. Я уже писал в статье про градиенты и нюансы работы с ними, но там всё же нет одной важной вещи. Glow. Мягкий glow. Мне кажется, что как у веб-разработчиков вечный вопрос “как отцентровать div?”, то у игровых это вопрос - “как сделать правильный Glow?”. Только задача для игровых в разы сложнее. Я для себя вывел простую технику, которая базируется на всё той же идее из статьи с акрилом. Как руки дойдут надо будет оформить это в репозиторий.
Идея в общих чертах звучит так. Отдельной камерой рендерим объект в сцене, который мы хотим подсветить. Уменьшаем текстуру до размера типа 256х256, размываем её гауссом, перекрашиваем в цвет глоу с учётом альфа канала и рисуем рассчитав uv по скринспейс координатам. Это достаточно сложно. Есть ещё техники “нарисовать весь глоу” - дорого по весу сборки, дёшево по гпу. Использовать идею из постпроцессинга, что глоу это по сути emission кромка плюс bloom. И так далее. В общем это сложно. То что это сложно не повод это не делать. Но если графический стиль не пострадает, если тень на кнопке или панели будет “жёсткой” - лучше делать жёсткую тень. Программисты будут очень рады.
Следите за пивотами
![](https://webcf.waybackmachine.org/web/20211006162304/https://habrastorage.org/getpro/habr/upload_files/d6c/a2f/6cd/d6ca2f6cd55c30aace56b999c36f11f6.jpg)
Это важно везде всегда и в 2д, и в 3д. Согласовывайте с программистами, как они планируют распологать объект, и где нужно поставить пивот. С текстурами - это больше к программистам и можно просто иметь ввиду. Потому что в юнити в настройках текстуры есть возможность задать пивот. А вот с теми же Spine анимациями пивот задаётся в спайне. И это очень плохо, когда программисты начинают костылями компенсировать позиции делая лишние трансформы или ещё какую-то дичь, вместо того чтобы сразу поставить пивот, где надо. Поэтому за этим очень важно и очень нужно следить, как со стороны программистов, так и со стороны арта, потому что в последствии это очень сильно упростит всем жизнь.
Вместо заключения
Существует ещё много инструментов типа того же Spine, чтобы делать оптимально анимации, потому что пнг секвенции - это очень дорого. Или же техник которые применимы в контексте конкретной игры типа “паллитр” (если число доступных цветов ограничено, то можно тратить меньше правил на их хранение) Но рассказ про отдельные нюансы работы с ними - это даже не одна статья.
Последний совет, который я бы дал игровым художникам помнить о том, что в тех же мобильных играх для вас максимальное разрешение 2048х2048. Топовые устройства уже спокойно относятся к 4к текстурам, но обычно мобильные игры делаются не для последней линейки айфонов.
Спасибо за внимание. О чём-то мог забыть, так что буду рад, если вы напишете об этом в комментариях.