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

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

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

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

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

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

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


Мяу-Мяу.

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

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

Стандартный метод текстурирования.

К этому моменту мы полноценно разобрали стандартный метод текстурирования, который применяется в играх уже очень давно. Метод достаточно прост - создается объект, или несколько объектов, для которых создаются отдельно текстуры в Substance Painter или в любом другом ПО. А в игровых движках эти текстуры просто накладываются на объект(ы).

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

Но суть остается одна - сам объект полностью текстурируется заранее в специализированных ПО, и на выходе всегда есть отдельный пак текстур для объекта.

Обычно, это 3 текстуры:

  • Base Color
  • ORM
  • Normal Map.

И обычно они имеют большой размер от 1024 до 4096 пикселей. Текстура без сжатия размером 4096х4096 пикселей с 1 каналом занимает 16 мбайт. То есть, все 4 канала в такой текстуре займут 64 мбайта.

48 Мбайт занимает одна текстура с 3 каналами, а нам надо 3 таких текстуры, что несомненно займет 144 мбайта. То есть, ради того, чтобы какой-то большой объект в кадре выглядел очень красиво и детально, нам потребуется выделить для него 144 мбайта памяти в нашей видеокарте. А теперь представьте 10 таких объектов в кадре?

Фиксируем основные проблемы этого метода.

  • Размер текстур. Качественные текстуры требуют большого объема видеокарты. У меня стоит 1060 c 6 гбайт оперативной памяти, но игра Control постоянно сбрасывает размеры текстур с ультра на высокие, а порой и на средние, потому что 6 гигов ей не хватает.
  • Количество текстур. На каждый объект создаются отдельные текстуры. И чем их больше, тем больше времени на загрузку/выгрузку и обработку текстур требуется.
  • Сложность редактирования текстур. Готовые текстуры очень сложно редактировать - нужно запускать заново проект в ПО для текстурирования, корректировать результат, выгружать, импортировать. А если поменяется чуть-чуть модель, и сменится развертка? Хорошо, хоть маски можно легко править, правда? Но и тут есть сложность - маски, нарисованные вручную придется перерисовывать с нуля. А если принято решение стилизовать какой-то тип фактуры у всех объектов? Теперь 100500 объектов нужно переделывать? И это на последних этапах работы над проектом?! 100% придется выкладывать проект, как есть - никто не будет согласен сделать чуть лучше за 500.000 долларов.
  • Время на текстурирование. Стандартный метод очень затратный по времени и ресурсам. Если у вас очень большой объем слоев фактур (кожа, металл, пластик, грязь под слоями, вторая фактура под краской, прозрачность, свечение и т.д.) - это все настолько долго рассчитывается под конец работы, что успеваешь пообедать, если процессор средне-доступного уровня.

И это только верхушка айсберга.

Существующие решения.

Часто разработчики начинают хитрить и стараются минимизировать риски, проделывая подготовительный большой объем работ:

  • Сжимать текстуры (например, в PNG). Теряется качество, но удовлетворяет потребностям.
  • Уменьшать размеры текстур. Из прошлой статьи мы узнали, что не всем объектам требуются текстуры большого размера. Поэтому часто на этапах концептов уже определяется то, насколько объект должен быть проработан. Так же уменьшение текстур может быть динамичным - чем дальше объект, тем меньше текстура и наоборот.
  • Зеркалировать текстуры. Минимизировать требуемый объем пространства для развертки, укладывая одинаковые острова в одно место на текстурном пространстве. Кто заметит, что этот Desert Eagle в первом Counter Strike (Может, и во втором), покрашен только на одну сторону, а вторая сторона - его копия? А качество текстуры тем самым выше. Или пример моей веселой корзины, в которой вертикальные палки через три покрашены одинаково. Смотреть здесь.
  • Создавать декали. Декаль, это текстура, которая проецируется на объекты прямо в игре. Можно сделать 10 декалей и накладывать их друг на друга под разными углами, тем самым минимизируя количество текстур и увеличивая вариативность. Первый попавшийся тутор на ютубе, в котором все становится ясно здесь.
  • Досконально проверять концепты, модели и технические требования. Найти неприятный элемент на самых ранних этапах в десятки (а то и в сотни / тысячи) раз дешевле, чем найти его на постпродакшне.
  • Создавать атласы текстур. Следующим пунктом мы разберем что это такое, и как это создается.
  • Повторять текстуры для разных объектов. Частично то же самое, что и атласы, но иначе. Очень наглядно это отображено в ролике про Assasin Creed II ниже.

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

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

Шикарная демонстрация того, на какие хитрости идут разработчики, чтобы минимизировать затраты на ресурсы.

Атласы тектур.

Атласы текстур появились с целью экономии количества текстур и попыткой сократить Draw Calls. Но в современных движках таким образом DC не уменьшаются уже давно (И не понятно, уменьшались ли ранее).

О Draw Calls можно почитать вольном переводе моего раба первой части книги "Ад Рендера". Оригинал здесь. Перевод здесь. Данные достаточно сильно устарели, но общее представление дают.
Мяу-Мяу.

Котик, Директор рендера

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

На UV-пространстве определяются места, в какой зоне какой объект будет расположен. И теперь на текстуре каждая зона будет отвечать за свой объект. В остальном все так же - красится через ПО для текстурирования, выгружается в движок.

Многие скажут, в что в таком случае выделять зоны в UV-пространстве нет смысла и можно просто упаковать острова максимально эффективно. А я спрошу - вам приходилось с нуля переделывать при такой раскладке один из объектов? Очень приятно осознавать, что в таком случае придется переупаковывать все развертки всех объектов в атласе с нуля. А значит, и переделывать все текстуры. С нуля.

Некоторые компании находили интересные пути решений - при создании Doom (2016) была создана атлас-текстура разрешением 16к х 8к, к которой относилось исполинское количество объектов - все это с целью экономии ресурсов и увеличении производительности.

В id Software это было названо Mega Texture. Кто ж знал, что сейчас такая текстура может быть наложена на 1 объект?
В id Software это было названо Mega Texture. Кто ж знал, что сейчас такая текстура может быть наложена на 1 объект?

Кстати, здесь можно почитать, как рендерится кадр в игре Doom (2016). Особенно обратите внимание на то, как определяется глубина сцены с помощью градиента серого - чем ближе к камере, тем объекты темнее.
Мяу-Мяу.

Котик, Начальник буферов

Итого.

Мы рассмотрели стандартный метод текстурирования и его слабости:

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

И что же дальше? Продолжать с этим жить? Покупать видеокарты с более объемной памятью и ничего не делать?

Термины и определения.

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

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

Параметры PBR - это параметры, которые определяют то, как свет будет преломляться на объекте, каким цветом будет объект и так далее. Типы параметров зависят от реализации PBR. в движках. Параметры обычно записываются в текстуры в виде значений в тексели от 0 до 255. Могут занимать от 1 до 4 каналов текстуры. Используются в текстурах для удобства работы с большим массивом чисел.

Не смотря на название, которое я дал параметрам, они могут использоваться не только для PBR. Параметры могут определять высоту ландшафта, использоваться для генерации миров (например, в Minecraft), генерировать детали через тесселяцию на объектах.

Но я оставлю это название, чтобы было проще ориентироваться, так как просто слово "параметры" слишком абстрактное.

Сама технология PBR - это технология рендеринга, которая может и не использоваться в движках. Зачем в пиксельной игре PBR, если там все только на текстурах?

Фактура - это уже более сложное понимание, так как слово "Фактура" отсутствует в английском языке. Есть только текстура, которая подходит под определение изображения (см. выше), а так же определяется, как фактура поверхности.

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

В английском языке есть слово "Материал" (Material), которое более часто используется в том смысле, в котором я имею в виду слово "Фактура". Но и с этим словом есть загвоздка. Дело в том, что в Unreal Engine 4 слово "Material" используется для обозначения шейдеров (Shader) - комбинации кода, который потом накладывается на объект и создает какую-то визуальную обертку для объекта (в прошлой статье мы создавали шейдер в UE4 для скамейки).

Для единого понимания я предлагаю на время прочтения этой статьи закрепить следующие понимания - Материал вместо фактуры, и Шейдеры вместо материалов.

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

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

Обратите внимание. Цвет этого материала кожи близок к черному, поэтому BaseColor так же близок к черному. Далеко ниже, на самом дне статьи, мы обязательно рассмотрим то, почему цвет BaceColor в материалах так важен.
Обратите внимание. Цвет этого материала кожи близок к черному, поэтому BaseColor так же близок к черному. Далеко ниже, на самом дне статьи, мы обязательно рассмотрим то, почему цвет BaceColor в материалах так важен.

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

Тут швы по другой причине, но мне было важно показать то, как они выглядят. Автор изображения: пользователь на сайте Gamedev.ru Modelist_max
Тут швы по другой причине, но мне было важно показать то, как они выглядят. Автор изображения: пользователь на сайте Gamedev.ru Modelist_max

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

Простой материал - это чистая поверхность (Pure Material). Например, кожа, дерево, рисунок ткани, пластик, металл и так далее. Чистая поверхность не имеет никаких повреждений или пятен. Может иметь мелкие царапины, которые просто подчеркивают особенность поверхности.

Иногда простые материалы называют еще Слоями Материалов (Material Layer), так они, как слои подкладываются друг под друга и через маски создают сложные материалы.

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

Сложные материалы еще называют Smart Material (умный материал). Однако это связано с тем, что в таких ПО, как Substance Painter умные материалы способны, например, определять грани объекта и генерировать в нужном месте внутренние маски повреждений, через которые отображается нижний слой материала. Или генерировать подтеки жидкостей / краски и так далее. То есть, в таких ПО умные материалы - это уже генераторы сложных материалов с определенными эффектами.

Пак простых материалов от Epic Games, который был представлен на скриншоте, можно скачать для UE4 абсолютно бесплатно. Скачать можно здесь. Настоятельно рекомендую его скачать и ознакомиться с ним прямо сейчас. А еще он нам понадобится для практики.
Мяу-Мяу.

Котик, Старший менеджер дополнений

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

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

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

Результат вычислений шейдера на картинке выше - вот такой материал:

Еще можно посмотреть на набор Smart Material'ов здесь. Это очень красивый набор сложных материалов. Настоятельно рекомендую к ознакомлению для общего понимания.

Маски - это текстуры / параметры PBR, состоящие из одного канала и определяющие, что будет отображаться, а что - нет. Маски могут быть жесткими и мягкими.

Жесткие маски - те маски, которые имеют тексели со значением только 0 или 1 (черное / белое). Такие маски не позволяют создавать полупрозрачные тона. С ними не сделать, например, материал стекла. Но они бывают нужны, например, для четкого разделения зон материалов.

Мягкие маски - те маски, которые имеют значения в текселях от 0 до 1. Они позволяют делать переходы более плавными и красивыми. Самые часто используемые типы масок.

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

- Маски для отметки зоны. Где можно подкладывать второй слой материала.

- Маски наложения второго слоя. Где второй слой будет 100% накладываться.

При использовании комбинации этих масок получается мощный результат. Более подробно мы разбирали это во второй статье.

Итого.

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

Система текстурирования слоев материалов.

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

А для начала разберемся в том, как это работает.

Принципы работы Системы слоев материалов.

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

Например вот такой красивый стилизованный бесшовный материал:

https://www.artstation.com/artwork/xR1NY Daniel McGowan

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

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

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

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

Вариант первый (нагло спертый у Epic Games).

Как сказано было выше - сначала готовятся простые материалы. После этого подготавливается сам объект.

Шаг первый. Подготовка модели.

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

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

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

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

То есть, теперь в ПО для текстурирования нам стали нужны не сами текстуры, а маски 2х типов и карта нормали под весь объект. Это сложно объяснять на словах, но я попробую, и потом закрепим практикой:

  • Маски-Зоны, которые определяют зону двух материалов. 1 канал может определять зоны для 2 слоев, поэтому мы можем использовать всю текстуру с 4 каналами, чтобы определить зоны до 8 материалов. Иногда здесь можно использовать жесткие маски, но не всегда. Помните, как мы в 3 статье обговаривали про маски зон? Это они и есть. Если не помните - перечитывайте 3ью статью и вникайте в суть, потому что без понимания этого дальше будет невозможно продвигаться.
  • Маски Слоев Материалов. Сейчас еще сложнее, но постарайтесь вникнуть в идею - когда мы маской-зоной определили где будет какой материал, на маске слоев материалов мы можем теперь отметить, где этот материал становится сложным материалом и делится на 2 и более слоев. Дальше в статье на практике мы разберем этот момент.
  • Общая Карта Нормали, которая теперь НЕ содержит в себе то, как должна отражаться поверхность (например, бугорки краски). Теперь эта карта содержит в себе только ВАЖНЫЕ технические неровности объекта и чаще всего фаски (если это хардсюрф). Так же в нее записываются перепады неровностей Масок Слоев Материалов, но об этом потом.

Это все, что теперь нам требуется от ПО текстурирования - создавать маски и основную карту нормали, которая на 90% теперь чиста и непорочна. Если вы еще ничего не поняли, то на втором шаге все станет более или менее понятно. Или нет. В любом случае, мы проведем практику, в которой все рассмотрим.

Шаг второй. Создание шейдеров.

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

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

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

И теперь самое интересное.

Помните про BaseColor, и что его теперь можно загружать одним каналом в серых тонах? Так вот, в шейдерах этот канал можно перемножить с любым нужным нам цветом, таким образом мы можем из одного материала, например, кожи, получить кожу любого цвета.

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

Это сложно объяснить словами, но я пытался =)

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

Вот здесь еще дополнительно запись стрима о том, как создавались подобные текстуры для игры Paragon:

А еще есть вот такой ролик, который примерно дает представление, как это выглядит изнутри:

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

Данный пол используется в одном из наших не анонсированных проектов.
Данный пол используется в одном из наших не анонсированных проектов.

Этот пол мы использовали в одном из наших проектов. Для этого пола мы использовали 2 материала:

  • Металлические полоски 32х32 текселя.
  • Металлические гексагоны 64х64 текселя.

Так же здесь использованы 2 маски:

  • Маска-Зона для разделения материалов. 64х64 текселя.
  • Маска Слоев Материалов, которая позволила наложить желтую краску на металлические полоски. 128х128 текселей.

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

Я думаю, как бы хорошо я сейчас не описал, у большинства из вас, особенно тех, кто впервые начал текстурировать и/или никогда не сталкивался с шейдерами в UE4, мозг поплыл в сторону. Поэтому.

Закрепим это на практике.

А за одно разберем, как работают шейдеры, и насколько там интересная математика =)

Чтобы было проще понять, я разбил практику на несколько очень подробных этапов. Если вам знакомы определенные моменты - просто пролистывайте до нового для вас =)

  • Для начала мы разберем тайлинг и его супер-полезность, создав простейший материал.
  • Сравним нашу карту нормали с картой нормалей от Epic Games.
  • Добавим немного лишнего и усложним материал.
  • Создадим по маске покраску для объекта.

Практика. Этап 1. Тайлинг и ее супер-полезность.

Что такое тайлинг? Это возможность использовать одну и ту же текстуру бесконечное количество раз для покрытия поверхности объекта. То есть, мы можем наложить на объект текстуру и растянуть ее на весь объект. А можем ее не растягивать, а повторять, тем самым увеличивая качество рисунка.

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

Для простоты работы мы сейчас возьмем 1 текстуру карт нормалей размером 64х64. Качать здесь.

Далее нам обязательно понадобится пак материалов от Epic Games для начальной работы - так будет проще на старте. Скачать и добавить здесь.

Для установки пака не требуется практически никаких усилий:

  • Скачайте пак через лаунчер Epic Games.
  • Добавьте пак в новый или существующий проект.

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

Article5Practice + Textures
Article5Practice + Textures

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

Далее создадим папку и в ней материал.

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

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

Так же подключим в BaseColor цвет виде Вектора из 4 каналов.

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

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

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

Например, чтобы нам настраивать тайлинг , нам нужно умножить координаты текстуры на одно число. Это число мы указываем в 2 пункте в виде скалярного параметра (Scalar Parameter). Найти эту ноду, как и все остальные, можно вправом меню под пунктом 5. Или вызвать это меню, кликнув в пустом пространстве ПКМ.

Немного о цифровых значениях и математике. Можно пропустить, но не стоит.

Скалярный параметр - это одно число. Оно может быть любым - отрицательным, положительным, целым или дробным - любым значением. Можно отнестись к этому. как к одному каналу с одним пикселем, который растягивается на всё UV пространство.

2 Vector - Это уже параметр, который хранит в себе 2 скалярных значения. Можно представить себе этот параметр, как двуканальный тексель.

3 Vector - Это параметр, в котором есть 4 значения. Да, 4 значения. И это связано с тем, что обычно с помощью этого параметра указывают цвет. А там, где цвет, там и альфа-канал.

Теперь нам нужно понимать, как будет происходить перемножение этих всех параметров между собой.

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

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

1Vector * 1Vector - это всегда просто перемножение двух чисел. Например, 5 * 8 = 40.

1Vector * 2 Vector - это перемножение скалярного значения (1Vector) на каждое значение двумерного вектора. То есть, если у нас есть скаляр = {2}, и 2Vector = {4, 3}, то их перемножение будет следующим = {2}x{4, 3}={2x4, 2x3}={7, 6}. То есть, результат всегда будет по бОльшему вектору. То же самое происходит и с перемножением скалярного числа с 3Vector.

1Vector * 3Vector - это перемножение скалярного значения (1Vector) на каждое значение трехмерного вектора. {2}x{4, 3, 8}={2x4, 2x3, 2x8}={7, 6, 16}.

Теперь рассмотрим чуть более сложные перемножения:

2Vector * 2 Vector - это перемножение чисел по своим позициям. Например, у нас есть 2 двумерных вектора {2, 5} и { 1, 3}. Перемножение будет следующим: {2, 5} * { 1, 3} = {2*1, 5*3} = {2, 15}.

3Vector * 3 Vector - то же самое происходит и при умножении трехмерных векторов: если 3V = {1, 2, 3} умножить на 3V {7, 9, 8}, то мы получим следующий результат:

{1, 2, 3}x{7, 9, 8}={1x7, 2x9, 3x8}={7, 18, 24}.

Часто мы либо перемножаем 1 канал (одно скалярное число) на различного размера вектора, либо перемножаем вектора на себе подобные размером вектора.

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

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

Очень редко, когда появляется необходимость перемножить 2Vector и 3Vector. Да и движок не рассчитан на подобные выражения. Поэтому для решения этой задачи 2V можно разбивать на отдельные скалярные значения и проводить математические действия раздельно, потом все складывая в кучу.

Можно и нужно спросить себя - а зачем мне это все? Почему бы дальше просто не текстурировать в Substance Painter и не получать результат, как это делают миллионы других текстурщиков?

Ответ прост - так сложнее, но эффективнее в разы.

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

Во-вторых, этот метод текстурирования выигрывает во всем стандартный метод. Поэтому за ним будущее.

Котик, Математиков помощник

Итак. Возвращаемся к текстурным координатам.

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

Изначально из ноды TextCoord приходят данные в виде 2Vector'а с значением размера текстуры - {1, 1}. И мы перехватыаем это значение и перемножаем на наш параметр, который я назвал TilingParam. То есть, это самое простое умножение скалярного значения на двумерный вектор.

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

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

Выделив TilingParam, его можно изменять в разделе деталей (пункт 4, значение по умолчанию).

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

Опять же, мы можем каждого канала ввести значения вручную, просто развернув default value:

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

Последний важный элемент, о котором я хочу вам рассказать - это то, что параметры со значениями в UE4 бывают двух типов:

  • Параметры. Могут изменяться во время игры.
  • Константы. Не могут изменяться во время игры.

Почему это важно? Шейдеры - это сложные математические формулы, которые выдают конечный результат. Если вы обратите внимание, то когда вы что-то в шейдере меняете - он компилируется (собирается) с небольшой задержкой. И чем сложнее код шейдера, тем дольше он компилируется. Результат компиляции записывается в память и потом в режиме игры просто воспроизводится.

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

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

Просто щелкните ПКМ по TilingParam и в меню увидите возможность конвертировать в константу. Но пока нам это не требуется.

Теперь нам нужно посмотреть, что же мы с вами натворили, поэтому сохраним материал и создадим из него Material Instance.

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

И откроем его.

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

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

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

Кстати, в панели Details есть наши параметры - Color и TilingParam. Нам надо поставить галочки рядом с названиями, чтобы мы могли редактировать их.

Укажите тайлинг на 50, а цвет поменяйте на любой более светлый. У меня получилось вот так:

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

Теперь чуть-чуть усложните материал, добавив настройки параметров Metallic и Roughness. Помните, что у этих параметров используется по одному каналу. А значит, достаточно скалярного параметра. У меня это теперь выглядит так:

Посмотрите, как начал играть свет при отражении от поверхности в отличие от первого варианта.
Посмотрите, как начал играть свет при отражении от поверхности в отличие от первого варианта.

Мы прекрасно помним, что все значения так или иначе не могут быть выше максимального диапазона. В параметрах это всегда от 0 до 1. Помните об этом, когда будете указывать параметры =)

Итого.

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

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

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

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

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

Практика. Этап 2. Сравнение размера карт нормалей.

В паке текстур Automotive Materials от Epic Games есть один шейдер, который нам нужен для сравнения. Располагается он здесь:

AutomotiveMaterials -&gt; Materials -&gt; Interior -&gt; Plastic -&gt; <b>MI_Plastic_Mold_Pyramide</b>
AutomotiveMaterials -> Materials -> Interior -> Plastic -> MI_Plastic_Mold_Pyramide

Это инстанс готового материала, в котором заменена карта нормали и изменены некоторые параметры. Выглядит материал вот так:

Сама карта нормалей выглядит вот так:

Размер 1024х1024
Размер 1024х1024

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

При этом я уменьшил само качество текстуры в 2 раза: здесь паттерн повторяется каждые 128 пикселей. Я вырезал его и еще уменьшил до 64 пикселей.

Моя карта нормалей:

Размер 64х64
Размер 64х64

Теперь я создам копию материала от Epic Games и вставлю свою карту нормали вместо оригинальной карты нормали, а тайлинг выкручу до 360 в обе стороны. Это будет соответствовать примерно размеру оригинала.

Теперь перед вами два шейдера. Попробуйте угадать, в каком из них моя карта нормали, а в каком - стандартная карта нормалей?

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

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

Котик, Директор зорких глаз

Если вы сможете увидеть разницу между двумя этими материалами - сообщите мне. Мне всегда были интересны люди, подмечающие невозможные детали =)

Так вот. Если нет разницы, зачем платить больше? Текстура карты нормали "весит" 1365 Кбайт, когда, как моя текстура занимает 5кбайт (12 на диске, 5 сжатая). Экономия просто колоссальная. А теперь представьте. что так можно до 50% фактур урезать.

Итого.

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

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

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

Практика. Этап 3. Добавление лишнего и усложнение материала.

Вернемся к нашему шейдеру, который мы собирали на первом этапе.

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

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

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

Текстуры с параметрами материала кожи мы возьмем из этого же набора - в папке с текстурами для кожи:

AutomotiveMaterials -&gt; Materials -&gt; Interior -&gt; Leather -&gt; Textures -&gt;<br />
AutomotiveMaterials -> Materials -> Interior -> Leather -> Textures ->

Возьмем текстуры кожи 6 версии (T_Leather_06). Обратите внимание на эти текстуры:

  • Все текстуры размером 4096х4096 пикселей.
  • Глубина канала пикселя в этой текстуре в 2 раза больше, чем в обычной (16 бит на канал против 8 стандартных).
  • Паттерн полностью уникальный на всю текстуру - то есть, его нельзя обрезать, сохранив качество и паттерн, а можно только уменьшить, сохранив паттерн, но потеряв в качестве.
  • Карта _R - Это карта для Roughness. Минус в этой текстуре в ее оптимизации - в текстуре задействованы все 3 канала, которые абсолютно одинаковы. То есть, 2 канала в этой текстуре просто так занимают такое огромное пространство в оперативной памяти.
  • Карта _BC - Это карта BaseColor. Если вы пройдетесь по каждому каналу (в настройках текстуры), то обнаружите. что она, как и текстура Roughness, имеет 3 канала, которые абсолютно идентичны. То есть, 2 канала в этой текстуре просто так занимают такое огромное пространство в оперативной памяти.

Заводите привычку оценивать ресурсы, с которыми вам предстоит работать. Возможно, они требуют доработки. Например, текстуры BC и Roughness можно было впихнуть в одну текстуру в разные каналы. И мы сэкономили бы уже немного на оперативной памяти. А разрешение в 4к для фактур - это огромный перебор. Можно было такого же качества сделать текстуру размером в 1к, или даже в 512. Но мы сейчас на обучении и пользуемся тем, что дают.

16-битные каналы - это более глубокая проработка качества оттенка цветов, чем 8-битная. Просто сравните - в 8 битах хранится 256 значений оттенков. В 16 битах - 65 тысяч.

Такие текстуры уже из разряда HDR. Но, знаете что? Мы все еще работаем с диапазоном от 0 до 1, и нам неважно, какую текстуру мы подключим =)

Добавим текстуры в материал.

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

Результат умножения можно соединить сразу с несколькими нодами (в данном случае с Texture Sample).
Результат умножения можно соединить сразу с несколькими нодами (в данном случае с Texture Sample).

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

  • Установим параметр цвета, чтобы можно было менять цвет материала кожи.
  • Установим множитель к Roughness и добавим параметр, чтобы мы могли настраивать интенсивность этого канала.
  • Установим функцию, которая будет регулировать интенсивность карты нормали, и добавим параметр для управления ей.
Обратите внимание, что мы из BaseColor и Roughness берем значения только из канала R, так как эти текстуры не являются оптимизированными, и все три канала повторяют одни и те же данные.
Обратите внимание, что мы из BaseColor и Roughness берем значения только из канала R, так как эти текстуры не являются оптимизированными, и все три канала повторяют одни и те же данные.

Две подсказки:
- В скобках указывается текущее значение параметра.
- Чтобы отключать соединения, зажмите ALT и кликнете по пину.

Теперь сделаем заключительные штрихи:

  • Добавим к нашей текстуре карты нормали пирамидок управление интенсивностью.
  • Смешаем карты нормали кожи и пирамидок.
  • Подсоединим результаты к завершающей ноде.
Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 5. Система материалов

Вот теперь сохраним наш материал и перейдем к инстансу материала, который мы до этого использовали:

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

Обратите внимание на параметр металла.
Дело в том, что в кодексе PBR все делится на 2 типа материалов - металл и не металл. Среднего значения не должно быть.

Но кодекс - это просто свод указаний, а не жёстких законов =)

Теперь я выкручу параметры примерно так, как себе представляю, а вы так - как пожелаете. И сравним результаты:

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

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

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

Пугаю сразу - дальше будет немного (или много?) математики.

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

А теперь вспомним, что нет такого понятия, как карты чего-либо. Есть каналы в текстурах, совокупность которых образует параметры для чего-либо. Так вот. Если мы взглянем на карту нормали пирамидки в канале B, то обнаружим очень интересный результат:

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

Это очень походит на маску, только оно еще не готово для полноценного использования. Давайте это исправим.

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

Сейчас сложно, но важно по шагам:

  1. Значения в каналах всегда от 0 до 1. Самый белый цвет - это 1. Черный - 0, а серый - между ними.
  2. Если мы умножим все значения на -1, то самый яркий станет самым наименьшим числом (1 * -1 = -1), а серые и темные цвета станут самыми большими ( 0.5 * -1 = -0.5, где -0.5 больше, чем -1 ).
  3. Далее мы прибавим к получившемуся результату + 0.9. Таким образом все наименьшие числа (самые яркие в начале) останутся за пределами 0, а средние тона станут в положительной зоне.
  4. Теперь, чтобы усилить серые тона, мы умножим весь результат на 5.
  5. Теперь все значения, которые мы получили - обрежем. Все, что ниже 0, станет 0, а все, что выше, станет 1.

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

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

Заметьте интересную тонкость. Расчет маски происходит по текстуре, пробегая каждый пиксель для получения результата. А это очень большой массив данных. Особенно для текстур 4к и выше. Но мы работаем с текстурой 64х64 пикселя.При тайлинге все расчеты ведутся только с основной текстурой, а данные для отображения берутся из первоначального результата. То есть, эта формула всегда будет работать только с массивом их 64х64 пикселей, даже если вы сделаете тайлинг на миллион.Поэтому тайлинг - бесплатный и выгодный способ текстурирования для видеокарт.
Мяу-мяу.

Котик, Внимательности мастер

Выберем из набора готовых текстур следующую текстуру:

AutomotiveMaterials -&gt; Materials -&gt; Textures  -&gt; T_Imperfections_Wipe_Mask T_Imperfections_Wipe_Mask
AutomotiveMaterials -> Materials -> Textures -> T_Imperfections_Wipe_Mask T_Imperfections_Wipe_Mask

В UE4 есть поиск по всем объектам проекта. Достаточно выделить папку Content (Корень папок) и в поисковой строке ввести название. Просто, правда?

Мяу-Мяу

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

Добавим текстуру в наш материал и сразу добавим к ней настройку тайлинга, как мы это делали со всеми нашими текстурами:

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

Далее немного сложно для понимания, но сначала сделаем, потом распишем:

  1. Умножим созданную нами маску зон на эту текстуру. Результат - новая маска, по которой будет размещаться пыль на материале.
  2. Добавим новый параметр цвета для управления оттенком пыли.
  3. Создадим переход цветов по новой маске через Lerp.
  4. Подключим результат к BaseColor.
Текстурирование, или что нужно знать, чтобы стать Художником по поверхностям. Часть 5. Система материалов

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

Я подсветил пыль синим, так как сейчас Roughness распространяется на всю поверхность шейдера, и внутри пирамидок не разобрать оттенков цветов =)
Я подсветил пыль синим, так как сейчас Roughness распространяется на всю поверхность шейдера, и внутри пирамидок не разобрать оттенков цветов =)

Итак, что же мы сделали:

  • Умножили созданную из карты нормали маску на маску пыли. Помните, тут простая математика. Если значение равно 0, то при умножении на 0 любое значение становится 0. Так работает маска зон. Умножив на маску грязи мы получили зону, в которой проявлялась пыль.
  • Добавили цвет пыли. Тут все легко.
  • Создали переход цветов через Lerp. Lerp - это функция интерполяции. То есть, она создает переход из состояния А в состояние B по маске. Когда приходит пиксель со значением 1, то отображается только А. Когда приходит 0 - только В. Все, что между, смешивается в процентном соотношении - если пришло значение 0.75, то смешение цветов будет в равном соотношении - 75% цвета А, и 25% цвета В. Поэтому синий цвет на скриншоте выше не везде идеально синий.
  • Подключили результат в принимающий параметр.

Почему пыль только внутри пирамидок? Представим, что нашу кожу только что протерли тряпкой, но не потрудились каждую пирамидку почистить =)

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

  • Смешайте по маскам параметр Roughness таким образом, чтобы внутри пирамидки не было такого перелива света - уменьшите степень отражения света.
  • Добавьте к пирамидкам возможность выбирать цвет внутри.
  • Уберите нормаль кожи внутри пирамидки. Как будто это перфорация пирамидками, а не продолжение кожи.
  • В Automotive Materials есть так же маска отпечатков пальцев. Наложите ее в качестве дополнения к Roughness только на кожу, словно кто-то хватался за нее и оставил ее.

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

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

Практика. Этап 4. Создадим по маске покраску для объекта.

Ох, как же далеко мы зашли. Вы еще не вымотались? Тогда продолжаем.

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

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

Как наложить материал на объект таким образом, чтобы пластик был на своем месте, а кожа была на своем? Самый простой способ - это нарисовать на объекте маску зонирования, по которой будет разделение на материалы.

Мы не будем брать в пример какой-то реальный объект. Как и в 2-3 статьях мы рассмотрим пример на плоскости, чтобы максимально быстро и сжато пройти этот этап.

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

Для этого создадим проект с Substance Painter. Теперь, когда нам нужно получить только маски, нам не нужно выбирать какой-то конкретный тип PBR или направление карты нормалей. Для конечного результата нам нужны лишь маски, которые можно создать при любом формате.

Размер маски выбирайте сами - лишь бы удобно было рисовать.

Далее нам необходимо:

  • Создать 2 папки с заливками. У каждой заливки нам нужно отключить все параметры PBR кроме Color, Height и Metal.
  • В каждом слое я настроил максимально разные цвета, чтобы было проще различать слои (до кислоты, у-ха-ха).
  • Назовем верхний слой Leather, а нижний - Plastic.
  • Установим значение Metal на 0 у Plastic (всегда черное), и 1 у Leather (всегда белое).
  • А вот Height установим на 0 у Plastic, и 0.1 у Leather.
  • Добавим полностью черную маску на верхний слой.

Примерно так:

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

Что? Елочка? Так все круто начиналось, и в конце елочка? И да-да, я рисую хуже детей в первом классе, я в курсе =) Мне норм =)
Что? Елочка? Так все круто начиналось, и в конце елочка? И да-да, я рисую хуже детей в первом классе, я в курсе =) Мне норм =)

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

Если вы не помните, как настраивается выгрузка текстур в SP, можно перейти к 4-ой статье и еще раз прочитать блок о настройках экспорта.
Мяу-Мяу

Котик, Напоминатор

Сначала нам нужно выгрузить карту металла качестве одноканальной текстуры (Grayscale). Мы специально разграничивали между слоями этот параметр (у одного 0, а у второго 1), чтобы мы могли выгрузить его в качестве канала.

При переносе параметра Metallic укажите, что это Grayscale.
При переносе параметра Metallic укажите, что это Grayscale.

Теперь добавим карту нормалей, которая у нас создается благодаря нашему параметру Height. Для этого создадим выгружаемую текстуру RGB и перенесем в нее Normal DirectX из секции Procedural.

При переносе укажите, что это RGB.
При переносе укажите, что это RGB.

Экспортируем и получаем следующие текстуры:

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

Завершая практику.

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

Так же обратите внимание на мои комментарии к картинкам, там расписаны тонкости некоторых решений.

Итого.

В этой практике мы разобрали:

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

Но это далеко не все, что мы можем.

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

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

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

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

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

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

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

Ниже представлены скриншот того, как в Epic Games создавали маски для летающего робота:

Обратите внимание на включенные параметры снизу справа c u0 по u7. Это созданные вручную параметры для Substance Painter. Вы можете сами создавать параметры и указывать их размерность в SP.
Обратите внимание на включенные параметры снизу справа c u0 по u7. Это созданные вручную параметры для Substance Painter. Вы можете сами создавать параметры и указывать их размерность в SP.

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

5 Этап. Дополнительный. Оптимизация.

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

Мы с вами создали сложный материал. Но как теперь его повторить при покраске другого объекта? Копировать и вставлять?

В программировании (поздравляю, вы чуточку теперь программист) есть такое понятие, как функция.

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

Мы уже сталкивались с функциями на практике постоянно, просто вы об этом не знали. Все ноды в шейдерах - это функции, которые получают в себя данные, внутри себя повторяют один и тот же код и выдают его в исходящем пине. Так. например, Saturate получает массив пикселей текстуры и каждому пикселю указывает его значение. А если оно выше 1 или ниже 0, то устанавливает 1 или 0 соответственно.

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

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

Я уверен, что вам не составит труда найти информацию о том, как создавать и использовать материальные функции =)

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

Например, у нас была ситуация, когда неопытный текстурщик решил показать свои знания в математике и создал фактуру из полосок, которая стоила больших расчетов. А текстура, подготовленная в SD нам обошлась в 30 раз дешевле.

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


Помните, что комбинация создания текстур для материалов в Substance Designer и создание материалов в шейдерах - лучшая из практик. Баланс. который таким образом достигается, привносит мир, свободу, справедливость и безопасность в ваш новый проект.

Общее Итого.

Этот раздел Итого настолько большой, что я его поделил на секции.

Тайлинг, размеры и качество.

Посмотрите на шейдер, который мы создали. Посмотрите на его внимательно.

Мы собрали два материала - кожу и (второй материал). Его размеры сейчас огромные! 293 Мбайт!

Посмотреть размер шейдера можно, кликнув ПКМ по нему и выбрав Size Map. Наверху справа можно переключить на отображение объема памяти, который будет требоваться в оперативной памяти видеокарты для работы с учетом сжатия текстур движком.
Посмотреть размер шейдера можно, кликнув ПКМ по нему и выбрав Size Map. Наверху справа можно переключить на отображение объема памяти, который будет требоваться в оперативной памяти видеокарты для работы с учетом сжатия текстур движком.

А теперь представьте, что все текстуры простых материалов, которые мы использовали от Epic Games, будут в разрешении 512 пикселей или еще меньше? Какой объем тогда займет этот шейдер? 2 мбайта? 500Кбайт?

А упадет ли качество при использовании более низких разрешений текстур? Мы видели сравнение и теперь понимаем, что - нет. Качество останется на том же уровне или даже выше.

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

Например вот такая маленькая текстура карты нормалей металла разрешением 32х32 пикселя:

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

Вот действительно, когда размер имеет значение =)

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

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

Так же есть маски для самого объекта и переключения материалов на нем. Изменение их размера в меньшую сторону ухудшает качество переходов между материалами. А эти маски нужны в большом количестве. Часто - на один объект по 2-3 текстуры с 3 каналами (удивились количеству масок или материалов?).

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

Текстуры в памяти.

Что касается текстур - сейчас, котятки, держитесь. Будет маленький крышеснос.

Мы сделали материал. Простой. Мы определили его в шейдерную функцию и теперь можем вызывать ее в любом другом шейдере. Но что на счет текстур?

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

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

То есть, внимание, мы можем построить огромную игру с высокой детализацией на уровне игры Control или COD: Warzone или даже выше и круче и детализированей, при этом используя только 200-400 Мбайт в оперативной памяти видеокарты. Как вам такое?

Я уже рассказывал, как Control сжирает всю мою оперативку в видеокарте и сбрасывает качество текстур, как только достигает предела. А представьте, если бы он был текстурирован методом текстурирования материалами? Сколько бы он занимал? 1 Гбайт? 500 Мбайт? Нужна ли была мне тогда видеокарта с 6 Гбайтами?

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

А в итоге получается, что мы можем создать из текстур 20-30 материалов на всю игру и корректировать их, как нам захочется.

Pipeline и дорогие переделки.

Помните, как в самом начале я приводил пример с огромной сложностью заменить какой-то стилистически важный материал в игре на последних этапах разработки? Сколько это могло вам обойтись? В 10.000 долларов? в 400.000?

Теперь это стоит 1 день работы одного человека.

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

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

Но задумайтесь. 1 человек. 5 рабочих дней. Сколько вам потребуется людей и времени, чтобы перебрать 500 моделей?

Осталась только проблема в самих объектах. Если мы начнем переделывать объект, то нам все еще нужно будет корректировать маски для него под новую топологию.

Однако согласитесь, поменять маски в шейдере куда легче, чем переделывать полностью все текстуры и шейдер?

Повторюсь, даже эта проблема решаема и еще лучше оптимизирована. Мы разберем это в 6 части.

Немного списка.

  • Мы избавились от необходимости создавать атласы текстур.
  • Мы оптимизировали Pipeline текстурирования.
  • Мы урезали объемы оперативной памяти (да-да, в 3090 будет 24 Гбайта, я знаю).
  • Мы ускорили сам процесс текстурирования - теперь нужно настроить материалы, и шейдер готов.
  • Мы можем позволить себе чуть-чуть схалтурить - настроить материал можно в любой момент, не тратя на предподготовку большое количество времени.
  • Мы добились высокого качества конечного результата за наименьшие телодвижения и объемы.

И что же дальше?

Художники по поверхностям.

Название профессии "Художник по поверхностям" - это не мной придуманное название. На сайте Epic Games вышла интересная статья под названием "Surface Artist", где приведено общее описание профессии и требований к ней.

Статья здесь.

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

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

Он должен уметь в шейдеры - создавать крутые шейдеры, которые не будут съедать FPS. А где шейдеры - там недалеко и программирование. В идеале. если художник по поверхностям будет знать HLSL (Яык программирования шейдеров в DirectX), GLSL, CGFX (OpenGL и библиотека шейдеров).

Он должен уметь в моделирование. Но скорее, знать и понимать основы работы вертексов (в 6 части мы разберем основные). И уметь скульптить, так как часто крутые материалы начинаются с создания карты нормали через скульпт.

В общем, эти статьи предназначены именно для вас, будущие художники по поверхностям =)

Что дальше?

Я 10 раз упомянул, что примеры, которые я расписал в этой статье устарели для нас уже на 3 года. Мы в нашей студии QberCat Studio зашли за это время куда дальше, избавившись от большого количества дополнительного груза.

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

Мы полностью избавились от масок для материалов, тем самым ускорили и упростили текстурирование еще сильнее.

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

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

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

На большинство ваших вопросов и оспариваний есть один ответ - попробуйте. Экспериментируйте. Перебирайте варианты.

Любое, даже очень сложное текстурирование, которое невозможно перенести на материалы, и можно сделать только старым методом - легко переносится на метод текстурирования материалами. Просто нужен опыт, нужна база, чтобы увидеть то, как это все красиво перенести. А для этого нужно много практиковаться и искать новые и новые решения.

Главное, что я вынес для себя при изучении чего-либо - это важность второго прочтения какого либо тутора/книги спустя некоторое время. Это позволяет намного лучше освоить материал. Дайте мыслям уложиться в голове, попрактикуйтесь немного и вернитесь к статье еще раз. Это позволит освоить материал куда сильнее. Ну и не забывайте выполнять практику.
Еще лучше, если вы будете выкладывать свои работы в комментариях.
Статья получилась очень большой, так как мой раб не захотел ее разделять на две части, хотя я ему это говорил. Освоить весь материал сходу может оказаться сложным.
Мяу-Мяу.

Котик, Высший Менеджер по обучению.

Если мои статьи были вам полезны - подписывайтесь на мой аккаунт, и я обязательно выложу что-то вкусное еще =)

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

Следующая часть Здесь.

7575
3 комментария

Отличная статья, спасибо!

1
Ответить