От тайлинга и смещения до атласа текстур на примерах смены обложки для книги и текстуры одежды и кожи персонажа

Данная статья посвящена таким параметрам материала, как Tiling  и Offset, и что интересного можно с ними сделать, если знать, как ими пользоваться. В статье рассмотрены примеры смены обложки книги и текстуры персонажей.
Открывая окно настроек материала в Unity 3D сложно не заметить такие параметры, как Tiling и Offset для каждого набора карт (основных карт/Main Maps и вторичных/Secondary maps). Тайлинг (еще называемый повторением, замощением, тайлингом, масшабом текстур) отвечает за количество повторений текстуры на выделенном ей для этого uv плоскости, другими словами тайлинг — это масштабирование текстуры на uv плоскости (или на 3D модели, если сказать проще).

nottiledandtiled

На рисунке показана текстура, “натянутая” на плоскость, причем слева значения для тайлинга равны 1 для осей x и y, а справа – равны 2 по обеим осям.
Использование тайлинга зачастую оправдано необходимостью размножить текстуру на поверхностях больших объектов, например, 3D моделей зданий, заборов, дорог, ландшафтов и так далее.

В качестве демонстрации того, что же такое тайлинг, создадим  плоскость 2 на 2 метра (условных единиц, если хотите) в Unity3D (вы можете также создать плоскость в Blender’е, только не забудьте создать для нее развертку).

createplaneunity3d

На рисунке показано меню создания примитивов в подменю 3D объектов (3D Objects) меню игровых объектов GameObjects.

Теперь вам нужна текстура, например, кирпичной стены. Вы можете скачать такую на Unity Asset Store, например, 10 High Resolution Wall Textures или одном из хранилищ бесплатных текстур, например, распространяемых под лицензией CC Zero (Public Domain Dedication), отлично подходящей для использования в коммерческих проектах. Я нашел текстуру кирпичей на http://www.texturemate.com/, скачал ее, и подогнал ее до  бесшовной квадратной текстуры кирпичей (1927 downloads) с разрешением 1024 на 1024 (ссылка открывает диалог скачивания текстуры). Импортируйте текстуру кирпичной кладки в свой проект и перетащите ее на созданную плоскость или создайте для плоскости материал, назначьте его плоскости (путем перетаскивания его на созданную на сцене плоскость) и перетащите текстуру кирпичей в поле Albedo в окне настроек материала.

materialassignunity

На рисунке показано меню назначенного плоскости материала. Зелеными стрелками показано два варианта назначения текстуры материалу. Нижняя стрелка представляет процесс добавления текстуры плоскости с автоматическим созданием материала. Верхняя – процесс добавления текстуры предварительно созданному материалу.

По умолчанию параметры тайлинга по осям x и y выставлены в 1, т.е. текстура повторяется всего один раз по оси Икс и по оси Игрек и занимает всю поверхность плоскости. Теперь заменим параметры тайлинга на 2 и 2 для x и y, как показано рисунке выше.
Так вот, тайлинг отвечает за то, сколько раз ваша назначенная материалу текстура будет повторяться по вертикали и горизонтали на созданной вами 3D модели, в данном случае — плоскости.

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

Стоит отметить, что тайлинг лучше всего работает с бесшовными текстурами, которые исключают появление несоответствий между левым и правым и между верхним и нижним краями расположенных рядом двух и более плиток («клонов») текстуры. Теперь, я думаю, вам стало понятно, почему тайлинг широко используется в 3D дизайнерами и разработчиками игр для текстурирования ландшафта (песка, земли, скал, воды), различных строений, в особенности — домов (стен и крыш домов), заборов (включая сетчатые, например, сетку-рабицу), бетонных конструкций, различных сооружений, дорог и многого чего еще. Возьмем, например, небесшовную текстуру кирпичей с того же сайта.

notseamlesstexture

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

Тайлинг позволяет уйти от использования одной текстуры только для одной конкретной uv-развертки (читай — 3D модели). Качество и скорость рендера 3D модели за счёт возможного повторения текстур возрастает в разы без необходимости создавать огромные по размеру (как в пикселях, так и в мегабайтах) текстуры. Но во всякой бочке меда может найтись ложка дегтя, способная все испортить. Чтобы нейтрализовать деготь, необходимо, как было сказано ранее, создавать бесшовные текстуры так, чтобы не было заметно того, что текстура «размножена» на 3D модели, избегая бросающихся в глаза элементов, например, отсутствующего кирпича на фоне остальных целых или яркого пятна на текстуре.

eyecatchingelement

На рисунке показана затайленная трижды текстура с бросающимся в глаза дефетом в кирпичной стене.

Если это, конечно, не является дизайнерской задумкой. К таким задумкам можно отнести, например, заклепки и болты по краям текстуры металлических панелей, sci-fi декали для панелей корридора, повторяющийся ярко выраженный узор, например, зигзаг, или надпись «Огнеопасно!», повторяющуюся по всей поверхности резервуара с пропаном и т.д. Посмотрите ,как смотрится одна из текстур металла с заклепками Yughues Free Metal Materials.

metaltexture

На рисунке показана затайленная (дважды) бесшовная текстура металла из ассета Yughues Free Metal Materials.

Однако затайливание при неправильном подходе может убить индивидуальность текстуры, превратив поверхности в однообразные и скучные полотна. Выходом из ситуации является использование дополнительных карт нормалей, проекторов, деталей, вторичных текстур (Secondary maps) и других способов размещения на поверхности модели чего-нибудь «вкусненького» или уже полупереваренных останков кого-нибудь «вкусненького».

Выше было рассмотрено лишь увеличение значения тайлинга, а что же будет, если выставить значения для осей x и y (на самом деле, для u и v в обозначениях uv развертки) меньше единицы, например, равными 0.5 и 0.5, или 0.5 по x и 1 по y?

tiling1050505

На рисунке показан пример, когда значения тайлинга имеют разные значения, например,  значение по х = 0.5 (слева), а значение по y = 1, и когда значения тайлинга по обеим осям меньше единицы и равны, например, 0.5 (справа).

Кирпичи стали больше в размерах… И это все? Не совсем. Это  значит лишь то, что в данном случае используется лишь половина и четвертая часть текстуры, а, значит, и uv развертки. Вариант со значениями мы рассмотрим в конце статьи, а сейчас давайте более подробно рассмотрим пример, когда значения для тайлинга по обеим осям равны 0.5 на примере книги и обложки для нее.

bookblender

На рисунке показана 3D модель книги с uv разверткой в Blender’е.

Чтобы вы могли сами попробовать то, что описывается в данной статье, я выкладываю 3D модель книги (1117 downloads) в формате fbx и две текстуры для нее. Одна текстура texture book 1024 (1834 downloads)  — совсем обычная, а вот вторая текстура книги texture book x4 (1938 downloads)  представляет собой атлас из четырех текстур книги.

texturebook1024

На рисунке показан предпросмотр текстуры книги.

texturebookx4

На рисунке показан предпросмотр атласа, состоящего из текстур для четырех книг.

Импортируйте книгу в Unity 3D вместе с текстурой. Перенесите ее на сцену и добавьте материалу книги текстуру. Книга и книга, что в ней особенного. Теперь замените текстуру на атлас текстур и в окне настроек материала  выставьте параметры Tiling для основной текстуры 0.5 для осей x и y, а для параметра Offset установите значения для x и y равными нулю.

twotextures

На рисунке: слева показана 3D модель книги в Unity3D с текстурой, параметры тайлинга и оффсета для которой выставлены по умолчанию, а справа — та же 3D модель книги, но с назначенным ей атласом текстур и значениями параметров тайлинга, выставленными в 0.5.

Опять получилась совсем ничем не примечательна книга, у меня – две совсем одинаковых книги. Теперь измените значение offset’а основной текстуры c 0 для x на 0.5.

booktiling05offset050rightunity

На рисунке: справа книга сменила текстуру, благодаря изменению значений смещения текстуры.

Воооот. Изменив значение параметра оффсета мы «сместили» текстуру на половину ее ширины влево (сказали, что точка отсчета для текстуры на uv плоскости у нас начинается не с координат {0; 0}, а с {0.5; 0}).
Offset с английского переводится как смещение и отвечает за расположение текстуры относительно координат uv развертки. uv развертка (или uv преобразование) представляет собой проецирование вершин 3D-модели на плоскоскость (uv плоскость, uv пространство). Координаты uv развертки, как правило, лежат между (0,0) и (1,1), но не всегда (пример превышения указанных значений продемонстрирован в статье про анимирование воды посредством смещения текстуры).

Начало координат uv плоскости находится в левом нижнем углу. Таким образом, для отображения левой нижней текстуры атласа значение смещения равно 0 и 0, для правой нижней — 0.5 и 0, как можно увидеть из рисунков выше. Для левой верхней текстуры значение смещения равно 0 и 0.5, а для правой верхней — 0.5 и 0.5 для осей x и y, соответственно. Что подтверждает приведенный ниже рисунок.

twobooks
На рисунке показана 3D модель книги с разными настройками смещения текстуры.
Как и в примере с водопадом и смещением текстуры через скрипт, здесь также можно менять обложку книги из скрипта.

Создайте C# скрипт с именем ChangeOffsetValues в одной из папок Assets проекта Unity. Откройте скрипт, щелкнув по нему дважды Левой Кнопкой Мыши и замените все, что находится внутри, на следующий текст.

Ниже приведен скрипт смены обложки книги по нажатию левой и правой кнопок мыши

Теперь “повесьте” данный скрипт на книгу, находящуюся на сцене (перетащите скрипт ChangeOffsetValues на экземпляр 3D модели книги, находящейся на сцене, либо выберите Левой Кнопкой Мыши книгу на сцене и перетащите скрипт в окно инспектора, под кнопку “Add Component”). Нажмите кнопку Play (запустите проект Unity 3D) и понажимайте правую и левую кнопки мыши.

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

public float xOffsetValue = 0F; — объявляем и инициализируем переменную xOffsetValue, отвечающую за смещение текстуры книги по оси X (U, если в UV пространстве).

public float xOffsetValue = 0F; – то же самое, но для y.

public Renderer rend; — объявляем переменную rend типа Renderer для кеширования компонента Renderer (на 3D модели должен висеть соответствующий компонент Mesh Renderer, отвечающий за визуализацию 3D модели);

rend = GetComponent<Renderer>(); — кешируем компонент Renderer;

if (Input.GetKeyDown («mouse 0»)) – проверяем, не нажата ли Левая Кнопка Мыши (mouse 0);

xOffsetValue = xOffsetValue + 0.5F; — изменяем значение переменной xOffsetValue на 0.5.

rend.material.SetTextureOffset(«_MainTex», new Vector2(xOffsetValue, yOffsetValue)); — устанавливаем новое смещение текстуры. Поскольку значение переменной yOffsetValue не изменилось, то смещение текстуры произойдет лишь по оси x на значение переменной xOffsetValue.

Код внутри следующего условия аналогичен предыдущему, за тем лишь исключением, что проверяется, была ли нажата Правая Кнопка Мыши («mouse 1»)  и значение смещения текстуры меняется по оси y.

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

Если взять 3D модель, созданную в редакторе персонажей Fuse, и посмотреть на текстуру экспортируемую с параметрами по умолчанию вместе с моделью, в разрешении 2048 x 2048, то можно увидеть, что она заполнена на 50 процентов. Остальные карты (карта нормалей, отражений и т.д.) построены по тому же принципу.

fitaunobl_packed0_diffuse_filled

На рисунке показана диффузная карта, экспортируемая вместе с персонажем (при отмеченной опции «Pack Textures and UVs»), созданным в редакторе персонажей Fuse. Как видно на рисунке, текстура занимает лишь половину диффузной карты.

На самом деле, приведенная на рисунке выше диффузная карта (ее еще часто называют просто текстурой) также представляет собой атлас текстур: здесь сгруппирована текстура тела персонажа на участке размером в 1024 на 1024 пикселей, а также текстура куртки, текстура штанов, текстура ботинок и текстура волос, каждая из которых занимает свой кусок текстуры размером 512 на 512 пикселей (при настройке персонажа данные размеры можно менять). Сделано это для облегчения компоновки текстур для различных модификаций персонажей, действительно, не будет же программа каждый раз создавать uv развертку для каждой комбинации различных частей тела и одежды персонажа. Все уже сделано до вас. Более подробно о том, как устроен Fuse изнутри, в частности про то, какие требования предъявляются к импортируемым в Fuse моделям персонажей и элементам одежды, требованиям к uv развертки и т.д., можно почитать на официальном сайте приложения в статье Creating Custom Content for Fuse.

Следовательно, можно объединить две текстуры в одну, расположив их друг под другом.

newfitacombineddiffuse

На рисунке показаны две представленные выше текстуры, объединенные в один атлас текстур.

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

changedtexture

Более подробно о модульных персонажах и смене одежды персонажей, рассказывается в отдельной статье Модульные персонажи или как переодеть своего героя. Мультиматериалы в Blender и Unity 3D. Мультитекстуры и как перенести сцену целиком из Blender’а в Unity3D.

texturechanging

Автор: Максим Голдобин
goldmaxval@gmail.com