Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Продолжаем серию уроков о том, как стать художником по поверхностям.

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Hello there! Моё имя Денис Кузнецов. Я - программист =)

  • Часть 1. Пиксель. Здесь.
  • Часть 2. Маски и текстуры. Здесь.
  • Часть 3. PBR и материалы. Здесь.
  • Часть 4. Модели, нормали и развертка. Вы ее читаете.
  • Часть 5. Система материалов. Здесь.
  • Часть 6. Погружение в систему материалов. Здесь.

Итак, котятки, погнали! =)

Модели, нормали и развертка

По моему скромному мнению, художник по текстурам должен отвечать за развертку. Не за саму развертку (ее стоит делать 3D-художникам или вообще отдельным UV-специалистам), а за ее укладку. Он должен определять, как острова должны располагаться, как должны быть повернуты и насколько сильно их можно потянуть в той или иной ситуации в зависимости от требований. И именно он должен определять скейл (масштаб) островов.

В этой части мы рассмотрим модели, развертку и нормали. Создадим текстуры для первой полноценной модели (хоть и простой) и настроим ее в Unreal Engine 4.

Предполагается, что к этому моменту вы разобрались с картой нормалей, и зачем она нужна. Потому что в этой статье мой раб будет очень часто о ней говорить. Если вы все еще плаваете в понимании, как считывается карта нормалей, какие каналы за что отвечают, то я бы настоял на том, чтобы вы сначала заскребли этот пробел и только потом продолжили читать статью. Так же предполагается, что вы уже знаете, что такое "развертка объекта" и "острова развертки". Но в любом случае, мяу-мяу.

Котик, Его величество

Модели и PBR. Практика

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

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

Лавка
Лавка

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

Так же я бы хотел сделать ее основу деревянной, а ножки — металлическими. Ну и немого накидать грязи. Соответственно, нам понадобятся 2 материала:

  • дерево
  • обработанный металл.

Ссылка но все это добро здесь.

Грязь мы не будем выносить в отдельный материал, а воспользуемся генератором в Substance Painter и создадим грязь внутри программы.

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

У нас были загружены 9 текстур + основной меш.
У нас были загружены 9 текстур + основной меш.

Обратите внимание, что в этот раз нам необходимо будет указать Normal Map Format — OpenGL. Мой раб уже писал в прошлой части, что карты нормалей считываются по разному разными программами. И данная карта была сгенерирована под программы, которые используют OpenGL.

Мяу-мяу.

Котик, Император императоров

Для начала рассмотрим максимально близко лавочку. Особенно нас интересуют грани объекта:

Все жесткие грани в моделях всегда являются идеально острыми.
Все жесткие грани в моделях всегда являются идеально острыми.

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

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


Мяу-Мяу.

Котик, Директор красивых картинок

Это первое ограничение модели.

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

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

Теперь давайте укажем эту карту нормалей, как основную (то есть, она всегда будет подкладываться к результату, как самый нижний слой без маски). Для этого нам необходимо открыть настройки основных текстур объекта и указать в параметрах карт нормалей нашу текстуру:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

И смотрим на результат:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Это первый самый известный и часто используемый метод борьбы с резкими гранями — запекать в карту нормалей фаски. То есть, модель все так же жесткая, но карта нормалей у ее граней начинает искажать свет, что создает иллюзию красивой мягкой фаски. В интернете можно найти кучу информации о том, как это делать. Для простых объектов, как эта скамейка, можно не делать хай-поли модели (и не запекать с нее соответственно), а сгенерировать карту нормалей с фасками в программах. Например, это умеет делать программа Modo. Наша скамейка имеет карту нормали, сгенерированную в Modo.

Но опустим тему запекания фасок и продолжим текстурирование скамейки.

Если у вас фаски не стали такими же гладкими, как у меня, а появилась иллюзия впадин — значит, при создании проекта в Substance Painter вы забыли поменять формат отображения нормали с DirectX на OpenGL.

Далее начинаем фасовать наши будущие материалы по папкам:

  • Создадим 2 папки под каждый тип материала.
  • Создадим в каждую по 1-му слою
  • В каждый слой вставим все текстурные карты.
  • Не забывайте о нейминге, чтобы потом не путаться:
Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Сейчас иерархия слоев нам не важна, так как данные материалы (металл и дерево) между собой пересекаться не будут — у нас не будет ситуации, когда сквозь дерево начнет проступать металл и наоборот. Но маски нам все еще нужны будут, так теперь нам необходимо ограничить видимость слоев на разных островах, поэтому сейчас добавьте черные маски на обе папки:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Fill Mode - тип заливки цветом. Маска - это все еще текстура, и мы можем ее красить, примерно, как в photoshop'е по выделенным зонам. В данном случае, мы выбрали зоны в виде островов развертки. А можно и по треугольникам и объектам.
Fill Mode - тип заливки цветом. Маска - это все еще текстура, и мы можем ее красить, примерно, как в photoshop'е по выделенным зонам. В данном случае, мы выбрали зоны в виде островов развертки. А можно и по треугольникам и объектам.

Кликнем на модели по основной скамье (если вы выделили маску дерева) и получим следующий результат:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Как видно на скриншоте — маска обновилась, и теперь на ней огромная белая полоса, которая расположена на месте острова. Покрасим таким образом всю скамью вокруг:

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

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

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Так же нужно залезть в трудно доступные места на стыках и отметить там нужные нам острова как для дерева, так и для металла:

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

Если вы внимательно осмотрите ножки, то заметите второе ограничение модели.

Развертка выполнена не корректно, и рисунок металла между сторонами ножек не согласуется — его фактура направлена в разные стороны, что визуально сильно бросается в глаза (направление отмечено стрелочками):

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Это именно ограничение, преодолевать которое можно путем выравнивания островов и их растягивания. Сейчас остров, на котором нарисована стрелочка вниз, выглядит так (выделен оранжевым):

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Для того, чтобы исправить проблему, необходимо, чтобы остров был выпрямлен в одну идеальную линию:

Заметьте, что все грани (edge) выравнены и параллельны. 
Заметьте, что все грани (edge) выравнены и параллельны. 

Если мы все сделали правильно, то мы решили это ограничение, но у нас возникло другое — потяжки:

Квадратики (чекеры) должны оставаться ровными, но не в этом случае.
Квадратики (чекеры) должны оставаться ровными, но не в этом случае.

Потяжки не страшны, если они не сильно заметны, или фактура на них не выдает их. Но с ними нужно быть осторожными, и иногда приходится мириться с тем, что могут возникать несостыковки материалов. Лишь бы это было незаметно =)

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

Потертости на лавочке.

Как мы знаем, на всех гранях всех вещей рано или поздно начинает откалываться краска, или кусочки материала. Там появляется большое количество царапин и сколов:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Для этого необходимо открыть настройки основной текстуры (где мы указывали карту нормалей), там выбрать Bake Mesh Maps.

В появившемся окне убрать все лишние галочки, оставив только Curvature и запечь ее, нажав на Bake [доп.название] Mesh Maps:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Когда создание текстуры закончится — она станет доступна в shelf под тегом Project:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

А так же эта текстура автоматически подключится в качестве основного параметра Curvature в настройках текстуры. Уберем ее оттуда:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Если создать новый слой вверху иерархии и установить в качестве параметра Base Color полученную текстуру, то мы увидим следующий результат:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Далее создадим папку, назовем ее Folder Dirt и поместим ее в папку с деревом НАД слоем с деревом. В этой папке создадим слой под названием LowLayer_Dirt, а на самой папке создадим черную маску, чтобы слой не накладывался на результат:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Укажем, что маска для грязи должна состоять из эффектов Fill, чтобы добавить текстуру, которую мы создали (curvature), и дополнительным эффектом «Levels».

Для чего нам нужен эффект «Levels» сейчас? Вы, наверное, обратили внимание, что маска для граней слишком светлая? Сейчас нам нужно будет обрезать цвета таким образом, чтобы оставить светло-белым места на гранях, а все остальное сделать абсолютно черным.

Конечный результат у вас должен получиться таким:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Таким образом мы создали "границу дозволенного" для грязи (Зону). Теперь надо ограничить саму грязь. Для этого нужно наложить черную маску на сам слой LowLayer_Dirt. После этого добавить эффект Fill, и в нем указать маску Dirt4, которая спрятана под тегом Procedurals:

Успеваете за мной?
Успеваете за мной?

Выше на скриншоте обведены так же дополнительные параметры маски Dirt 4. Дело в том, что это не текстура в том формате, в котором мы привыкли представлять ее. Это генератор случайных чисел по определенным правилам.

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

Теперь измените параметр Height в слое LowLayer_Dirt на -0.35 и посмотрите на результат:

Ляпота =)
Ляпота =)

Повторюсь. Сейчас наша цель не в качественной идеальной покраске лавочки, а работа с основами и тренировка работы с масками и материалами.

Домашнее задание.

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

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

  • залакируйте дерево
  • создайте царапины на лаке (те царапины, которые видны только под углом, потому что они продавливают лак, но не повреждают дерево)
  • создайте царапины под лаком

Кидайте в комменты ваши работы, делитесь результатом - смотрите, кто что сделал. Таким образом вы сможете улучшить свои навыки.

Итого

Мы разобрали:

  • Как текстурировать модели с помощью масок.
  • Как наносить грязь, сколы и царапины с помощью масок.

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

Котик, Маскировочный профессор

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

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

На этом мы закрываем большую тему того, как можно текстурировать объекты для игр в рамках PBR. Всё остальное — техники. Моя задача рассказать суть, основу всего этого, чтобы у вас не было в дальнейшем вопросов по типу «А чем отличается карта Roughness от Metallic и Normal map?» (сразу отвечу — ничем), а появились вопросы — «А как это можно усовершенствовать? Как сделать лучше и эффективнее?»

Настоятельно рекомендую вам тренироваться и баловаться с масками, их иерархией и смешением масок. Это самая важная часть текстурирования после понимания каналов. Когда мы перейдем к созданию сложных материалов в UE4, там жонглировать масками так просто не получится - там будет решать математика, и ваши навыки понимания иерархии, которые вы получите в Substance Painter, облегчат вам жизнь в 10 миллионов котиковских раз.
Мяу-Мяу.

Котик, Рабовладелец

Мы разобрали несколько ограничений, у которых существуют решения.

  • Ограничение с фасками.
  • Ограничение с расположением островов.

И то и другое ограничения так или иначе можно обойти. В первом случае мы создаем карту нормалей, которая имитирует изгиб, во втором случае мы тянем острова и жертвуем деталями (создаем потяжки) ради общей картины.

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

Развертка

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

Отложим на время в сторону Substance Painter. Не закрывайте проект, он нам пригодится позже, когда мы будем экспортировать текстуры в Unreal Engine 4.

В этом куске статьи мы рассмотрим развертку объектов, плотность островов и наконец-то изучим такое явление, как плотность текселя.

И начнем с текселя.

Тексель

Тексель — это текстурный пиксель (ба-дум-с).

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

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

С этого момента, мы начинаем говорить правильно — пиксель и тексель. Пиксель — мониторный элемент. Тексель — текстурный элемент.

Так вот, повторим пройденное, тексель — это мнимая единица отображения информации. Она существует только в цифрах (массив цифр из каналов), но, чтобы нам было проще работать с параметрами рендера, были введены текстуры, как визуальный заменитель массивов цифр.

Думаю, никому не было бы приятно разрисовывать космический корабль одними только цифрами, держа в голове представление, что тексель в 8 ряду и в 453 столбце должен быть на 1 значение меньше, чем тексель в 284 ряду и в 112 столбце. Поэтому для более быстрой работы такие цифры визуализировали в текстурных каналах. Вам же проще тыкать кисточкой в Photoshop'е, правда?
Мяу-Мяу.

Котик, Кораблей директор

Рендеры (системы визуализации) считывают цифры текселей в текстурных каналах, обрабатывают их и отображают их в качестве квадратиков (текселей).

Опять же. Отображение текселя в виде квадратика — дело условное. И зависит оно в частности от плотности и натяжения островов развертки модели.

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

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

Один из островов я сжал
Один из островов я сжал

Развертка левой и правой стороны расположилась вот так:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Часто в 3D-редакторах объектов есть возможность проследить, насколько сильно сжат или растянут остров развертки. Например, в Autodesk Maya это выглядит вот так:

Где белым отражается корректный остров,  красным отображается сильное сжатие, а синим — растяжка
Где белым отражается корректный остров,  красным отображается сильное сжатие, а синим — растяжка

Плотность островов

Острова должны быть так же отмасштабированы между собой. То есть, площадь, которую занимает остров на модели, должна соответствовать площади другого острова и всех островов между собой. В противном случае, получится так, что один остров реальной площадью 20 кв.см будет занимать 20% площади текстурного пространства, а остров с реальной площадью в 100 кв.см будет занимать 5% площади текстурного пространства. И отсюда получится разногласие в отображении количества текселей на острове:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

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

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

Выше картинка из статьи хаброчанина <a href="https://habr.com/ru/users/osmandos/" rel="nofollow noreferrer noopener" target="_blank">Osmandos</a>. Его статья вот <a href="https://habr.com/ru/post/315146/" rel="nofollow noreferrer noopener" target="_blank">здесь</a>. Обязательно к прочтению. Osmandos
Выше картинка из статьи хаброчанина Osmandos. Его статья вот здесь. Обязательно к прочтению. Osmandos

Размер текстур

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

Раб ошибся.
Мяу-Мяу.

Котик, Главный по отказам.

На самом деле, надо обратить внимание теперь на тексели кубика относительно пикселей монитора. Заметим, что тексели на нем (черные и белые квадратики, в данном примере) очень большие (опять же — условно. Представим, что в текущей текстуре квадратики — это тексели). Даже если мы выровняем все острова, мы все еще видим черные и белые квадратики на сторонах куба:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Это говорит нам о том, что текущий размер текстуры очень низкого качества (разрешения), поэтому мы видим тексели. Но так ли это?

Представим, что текущая текстура (ее обычно называют «чекер» (Checker) — текстура для проверки корректной настройки островов) имеет размерность 63 на 63 текселей. И сейчас мы видим этим тексели, потому что объект расположен к нашей камере настолько близко, что размер одного текселя занимает площадь 30х30 пикселей монитора (условно).

А если мы отдалим куб от камеры подальше?

Если смотрите на эту картинку с телефона, то она там очень страшная =)
Если смотрите на эту картинку с телефона, то она там очень страшная =)

Попробуйте теперь разглядеть тексели на этом кубе?

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

То есть, размер текстур зависит очень сильно от площади, которую занимает развертка модели и от расстояния объекта до камеры. Если объект будет находиться на достаточно большом расстоянии от нас — нет смысла ему выдавать текстуры 8к на ноготок. Даже если вы делаете текстуры для фильма — никто просто не увидит белую полоску на ноготке девушки, рука которой занимает 0.5% от площади экрана.

На эту тему есть еще достаточно полная статья здесь. И перевод здесь.

Итого

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

Не забывайте выравнивать острова относительно друг друга — это важно и очень сильно влияет на восприятие. Если вы откроете, например, игру Fallout 4 и начнете диалог с каким-нибудь NPС, то заметите, что качество текстур на одежде персонажа очень низкое, а лицо имеет максимального размера текстуры:

Приоритеты =)
Приоритеты =)

Стоит помнить, что в играх часто специально занижают размер текстур в угоду производительности. Да и кто смотрит на одежду, когда у персонажа такое интересное лицо со шрамами?

Большие размеры текстур занимают большое пространство (в памяти, я имею в виду). Поэтому многие разработчики принимают тяжелое решение — что урезать, а что оставить, лишь бы игра не тормозила на вашем ПК / консоли / телефоне. Однако, к этому вопросу мы еще вернемся и рассмотрим новейшие методики, которые позволяют избегать таких неприятностей.

Запекание текстур

Что такое — запекание текстур?

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

Грубо говоря, в Substance Painter мы накладываем слои за слоями через маски и прочие хитрости, чтобы добиться конечного результата. Мы работаем над тем, как должна выглядеть конечная модель, смешивая различные варианты материалов. Но, если вы заметите — чем сложнее будет ваша комбинация слоев, масок и материалов, тем сложнее будет обрабатывать ваши изменения программа. Дело в том, что Substance Painter (Любая другая программа для текстурирования) сверяет каждое ваше изменение и просчитывает в реальном времени ВСЕ созданные вами слои и каналы (а я напоминаю, что вы можете еще и свои каналы добавлять в слои для всего-чего-угодно), которые приходятся на тексель.

А когда мы довольны результатом и готовы выгрузить его в игровой движок, то мы просим Substance Painter сделать последние расчеты и создать нам текстуры с параметрами для цвета каждого пикселя, и 3 дополнительные текстуры с параметрами Metallic, Roughness и Normal Map. Это позволит нам не выгружать в игру тонны масок и дополнительных материалов, не заставлять движок рассчитывать все заново, а просто предоставить ему готовый результат, который он преобразует в текстуры для модели за мгновение.

Плата за это - практически полное отсутствие гибкости в настройках текстур в игровых движках.
Мяу-Мяу

Котик, Главный по сборам плат

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

Напоминаю, что в текстурах 4 канала. И мы можем в игровых движках получать данные каждого канала отдельно, а значит, мы можем в текстуру с 4 каналами записать в каждый канал свои данные. В канал R, например, параметры для Metallic, а в G - для Roughness.

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

О_О
Мяу-Мяу

Котик, Глава отдела офигиваний

Теперь возвращаемся в Substance Painter, в наш проект (надеюсь, вы его не закрыли), и начнем выгружать текстуры. Для этого откроем окно выгрузки текстур (File — Export textures):

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Как видим, здесь 4 текстурных файла, которые должны экспортироваться, против 9 файлов, которые мы загрузили.

Но нас они не интересуют, так как стандартные настройки, а нам нужны свои личные (или по стандарту студии, в которой вы работаете). Поэтому перейдем в окно Configuration:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Теперь обратим внимание на панели справа:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Input Maps — это список параметров, которые мы использовали при текстурировании (напомню, что параметры содержат в себе каналы). Большая часть из них имеют названия, так как используются для PBR для конкретных целей. Есть 8 параметров по одному каналу (от 0 до 7), которые доступны для редактирования, но Substance Painter не знает, зачем вам они могут пригодиться, поэтому у каналов стандартные названия User0 — User7. А вообще, они нам пригодятся в будущем.

Converted Maps — это список текстур, которые зависят от типа рендера. Например, Normal Map зависит от движка. И нам нужно знать, какой API использует движок — DirectX или OpenGL, чтобы выбрать корректную карту нормалей для него. Поэтому Substance Painter выделяет эти карты в отдельную категорию, так как конечный результат их будет зависеть от того, что вы выберете.

Mesh Maps — те текстуры, которые вы загрузили вместе с объектом или сгенерировали во время работы над ним. Мы загружали 9 текстур. 8 из них относились к слоям (материалам), а 9-ая карта нормалей для фасок уже относилась напрямую к объекту. Кроме карты нормалей мы создали еще карту Curvature для наложения по ней сколов. Эти карты относятся именно к объекту и не могут использоваться в качестве основы для материалов, поэтому они вынесены в отдельный список.

Теперь рассмотрим панель создания текстур:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Это кнопки, нажав на которые вы создаете 1 файл текстур (точнее, подготавливаете все для его создания).

Gray — создает текстуру с одним каналом. В этот канал мы можем расположить любые наши параметры, которые требуют один канал — Roughness, Metallic, Specular, Emissive, Hight и т.д.

RGB — создает текстуру с 3 связанными каналами. То есть, это предназначается для таких параметров, как цвет (BaseColor), карта нормалей. То есть, для всех параметров, которые используют 3 канала для полноценной реализации себя.

R+G+B — создает текстуру с 3 не связанными каналами. То есть, у нас текстура с тремя Gray — каналами. Можем указать параметр с 1 каналом в каждый канал текстуры отдельно. Часто это используется для ORM — (Occlusion-Roughness-Metallic). То есть, в первом канале хранится Ambient Occlusion, во втором хранится Roughness, в третьем — Metallic.

RGB+A — как вы уже догадались — 3 связанных канала и 1 не связанный.

R+G+B+A — четыре не связанных канала.

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

Правильно, минимум 3 текстуры:

  • RGB — BaseColor
  • R+G+B — ORM (Occlusion-Roughness-Metallic).
  • RGB — Normal Map

Нажмите поочередно на нужные вам текстуры, и у вас получится такой список:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Сейчас нам необходимо указать, какие параметры в каких каналах будут храниться. Для этого просто перенесите из Input Maps параметры в нужные каналы. Карту нормалей нужно перенести DirectX, так как в UE4 используется такой формат чтения нормалей.

В итоге, у нас получится следующий набор:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Теперь переключаемся обратно в Export. Там мы:

  • Указываем путь, куда сохраняться.
  • Выбираем созданные нами преднастройки в параметрах Config.
  • Выбираем тип текстур — Targa.
  • Нажимаем Export.
Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

И вуаля — экспорт текстур прошел успешно. Откроем текстуру BC (BaseColor) в Photoshop и посмотрим на нее:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Вы помните, как мы создавали 2 разных материала в разных слоях? Substance Painter сложил все слои, высчитал результат конечного варианта текстуры, которая будет покрывать объект, и «запек» все тексели ровно так, как вы замаскировали их. Все то же самое он сделал с Normal Map, Roughness и Metallic.

Если мы откроем карту ORM в Photoshop, перейдем режим отображения каналов и выберем последний (синий), то мы увидим запеченную карту Metallic:

Metallic мы расположили в B канале.
Metallic мы расположили в B канале.

Дерево не является металлом, поэтому на карте в том месте, где расположены острова дерева у нас черные пиксели, что означает 0 (не металл). Ну а металлические ножки окрашены в белое (1 - металл).

Итого.

Мы научились создавать готовые текстуры для игрового движка.

Важно. Сейчас мы научились запекать текстуры, делая весь расчет создания этих текстур в Substance Painter. То есть, мы сделали все для того, чтобы получились готовые текстуры, которые теперь мы можем использовать в разных движках (с оговоркой на обработку некоторых параметров PBR).

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

Чтобы рассчитать, как правильно отображать цвет и свет от текселя — видеокарте нужно произвести расчеты на каждый тексель. И это не будет никак зависеть от того, сколько пикселей у вас на мониторе. Это будет зависеть от того, сколько текселей используется при формировании текстуры (в Substance Painter мы используем стандартные настройки, значит, использовали 1024*1024 текселей). То есть, чтобы отобразить корректно текстуру, Painter'у нужно посчитать каждый пиксель, и учесть в нем все слои, которые вы создали. Это трудоемкая задача, поэтому раньше (да и сейчас) PBR-текстуры создавали в основном в программах для текстурирования. и только потом вставляли готовые варианты в игру, уменьшая нагрузку на видеокарту.

Unreal Engine 4

Ну и наконец выгрузим наш объект в UE4 и посмотрим наш результат. Я не буду расписывать, как открыть UE4, как создать проект, как вообще его устанавливать и какие там кнопки жать. Для этого есть очень хорошие курсы от Flakky. Курсы все располагаются на его сайте uengine.ru. Сейчас мы рассмотрим только импорт нашей лавки и получившихся текстур, создание примитивного шейдера и подведем итоги.

Для начала откроем проект и создадим в нем папку «Bench», в которую мы скинем все наши выгруженные текстуры и сам объект. Чтобы импортировать все текстуры — достаточно просто перенести их из браузера в проект. Они без проблем импортируются и никаких настроек дополнительно не попросят. Что касается объекта, то при его импорте Unreal Engine попросит вас указать некоторые настройки. В целом, ничего менять не нужно, кроме 2 параметров. Их надо отключить:

Эти параметры отвечают за импорт текстур, а они у нас отдельно хранятся.
Эти параметры отвечают за импорт текстур, а они у нас отдельно хранятся.

В итоге, в нашей папке 3 текстуры и 1 объект:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Теперь в любом свободном пространстве в браузере проекта нажмем ПКМ и выберем Material:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Назовите его M_Bench.

Откройте его и перетащите в него все наши текстуры. Получится такая картинка:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Все эти элементы на графе - ноды (Node) - контейнеры, которые позволяют визуализировать настройки так, чтобы с ними было удобно работать даже новичку. Белые пины на текстурах (нодах слева) обозначают, что отсюда подаются сразу три канала. А вот красные, зеленые и синие — каждый канал отдельно. Последний сероватый — это альфа-канал, но в наших текстурах его нет, поэтому использовать этот пин мы не будем. Справа большая нода, которая принимает в себя параметры, суммирует их и создает полноценный результат всех текстур - материал, который мы потом накладываем на объект.

Весь принцип работы текстур в Substance Painter используется и здесь (и в любом другом игровом движке) — вы указываете, какие параметры для чего нужны, и программа выдает результат. В данном случае, большую часть расчетов взял на себя Substance Painter, Unreal Engine же просто сейчас будет складывать готовые результаты Painter'а. Но не расстраивайтесь - система материалов в UE4 настолько сильная, что Substance Painter покажется песочницей для детишек =)

Нам осталось только правильно подключить пины и попросить движок рассчитать нам результат:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

А почему я не воткнул из текстуры ORM красный канал в Ambient Occlusion? Я уже как-то упоминал, что AO считается устаревшей, так как АО часто рассчитывается в реальном времени. И в ноде материала есть пин Ambient Occlusion, но он работает только при запекании света на объект. В противном случае он просто не учитывается.

Итак. У нас готов самый простой шейдер (материал), и мы можем наконец-то покрасить нашу лавку. Для этого откройте лавку в UE4, кликнув по ней 2 раза ЛКМ. И перетащите материал из браузера проекта в слот для материала:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

Ну вот. Теперь вы получили свой первый готовый объект.

Результат вы можете увидеть сами, а я лишь подведу итоги.

Итого.

В очень простой форме мы научились создавать первые шейдеры в движке UE4. Вы спросите — а почему это называется Material, а не шейдер в самом движке? Так проще объяснять, что это за формат построения текстур такой — это материал, который накладывается на объект, и объект становится красивым. Но, как я писал выше, возможности шейдеров куда больше (намного, в сотни котиков больше), чем просто отобразить текстуры на объекте.

Дополнительно. Решение проблем с фасками.

Выше я обозначил проблему с фасками и как ее решить. Но есть второй способ, который мы в рамках этой части рассматривать не будем полноценно — это создание фасок на модели выравнивание нормалей вертексов (Еще одна нормаль? Чтооо? О_О) таким образом, чтобы поверхность меша создавала иллюзию красивой фаски. И этот метод даже в чем-то более экономичный в производительности, чем метод с картами нормалей, а уровень красоты его запредельно высок по отношению к обычному текстурированию фасок. Вот пример двери, которая стоит в одном из наших игровых проектов (пока что не анонсированных):

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка
Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Плюс этого метода в том, что мы создаем красивую фаску, при этом, кол-во вертексов практически не увеличивается, так как жесткие грани — это всегда 2 вертекса в одной точке, а мягкие грани — это 1 вертекс, и увеличивается кол-во треугольников для отрисовки:

Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 4. Модели, нормали и развертка

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

Последнее Итого в это статье.

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

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

Можно смотреть больше уроков и совершенствовать свои навыки. Например, в Substance Designer есть огромная наковальня генераторов, создав которые, вы можете использовать в качестве их генераторов слоев в Substance Painter. И все те маски, которые были для грязей, уже не создавать вручную, а реализовывать на уровне функций, которые все сделают красиво за вас.

Нужно всегда помнить, что мы рассматриваем диапазон значений от 0 до 1. Это важно, потому что стандартные текстуры имеют 8 бит на канал, а HDR-текстуры имеют более широкие каналы (от 16 бит и более), а значит, диапазон чисел там намного больше, чем 0 до 255. Но это все еще диапазон от 0 до 1.

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

Но так ли это? Мы действительно достигли предела в текстурировании и лучше уже не получится?

Или есть куда ещё расти?

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

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

Ссылка на предыдущую часть здесь.

Ссылка на следующую часть здесь.

8585 показов
11K11K открытий
10 комментариев

Статья супер!
Все 4 главы как по маслу шли и тут под конец... "жесткие грани — это всегда 2 вертекса в одной точке, а мягкие грани — это 1 вертекс" как иглой в одно место. Это как вообще? Почему жёсткая грань 2 вертекса? Мать с рождения рассказывала что куб - 8 вертексов.... а выходит 16? Или иметься ввиду с учётом того что развёртка режется по острым углам (модель + развёртка = 16 вертексов на видеокарту).
Даже не знаю как это загуглить чтоб почитать. Наставьте на путь.

И вторая игла тут же добивает. "карта нормалей нужна в 99% случаев только для создания фасок и переноса каких-то уникальных узоров. Во всех остальных случаях она формируется их фактуры материалов"
Что значит из фактуры материалов? А как мне показать трещинки на дереве или облупившуюся краску... из фактуры материалов я могу вытянуть только ЧБ карту и засунуть в бамп или дисплейз проведя через фильтры и это не всегда то что нужно. Что вы имели ввиду?

Ответить

Хохохо =) Тебе еще столько интересного открывать =)
По поводу вертексов и кубика.
Ты не совсем правильно посчитал вертексы. Если брать куб со всеми жесткими гранями, то вертексов будет 24, а не 16 или 8. Связано это с тем, что для каждого полигона при жестких гранях требуется направление нормали. Каждый параметр нормали - это новая точка. То есть, если в точку приходит 3 полигона, и все три полигона с жесткими гранями, то точка расщепляется на 3 точки.
Более подробно я распишу это в 6 части. Она примерно на 70% уже готова =)

На счет фактуры и трещинок - это все, надеюсь, я объяснил в пятой части. Прочти ее и дай знать, все ли там расставило точки по фактурам, или остались вопросы =)

Ответить

Лютая годнота , огромное спасибо !

Ответить

Спасибо)

Ответить

Статья топ

Ответить

Спасибо =)

Ответить

Вот моя работа) Спасибо за статью!

Ответить