Найти тему

Основы шейдеров в Unreal Engine 5

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

Условно материалы можно разделить на несколько категорий по их назначению.

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

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

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

А уже после переходить к специфике назначения того или иного шейдера.

Предлагаю рассмотреть основные узлы, которые активно используются при создании логики материала:

1. Результирующий узел

-2

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

Базовый цвет, оптические свойства, типа бликов или шероховатости, контактные тени, формирующие микродетализацию наряду нормалями, свойства металличности и прочее…

2. Текстурный объект

Узел, позволяющий внедрять в логику материала текстуру.

-3

3.Текстурный семпл

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

-4

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

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

4. Узлы типа константы

-5

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

Его смысл возникает только в контексте, когда мы прикладываем константу к какому либо механизму (логике):

-6

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

В то же время, если вывести в константу значение 1 (оно является максимальным значением в RGB-поле):

-7

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

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

-8

На изображении ниже представлена 4-х мерная константа, так как помимо трех цветов подключен еще и 4-ый в виде альфа-канала.

Кроме исходного состояния узлов многие из них можно параметризировать.

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

-9

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

-10

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

-11

Экземпляр наследован от мастера со скаляром с названием “Пример”

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

Это часто применяется при создании, например трим листов или D-Buffer декалей, в одном экземпляре я например могу включить эмиссию, а в другом нет.

5. Static Switch Parameter

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

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

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

Например, подключать лужи на ландшафтный шейдер или подключать снег.

Все в таком духе:

-12

6. Landscape Layer Blend

Еще один важный узел, расщепляющий логику на слои.

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

Этот механизм используется при создании материалов для ландшафта (вторая часть этой статьи будет посвящена рассмотрению одного из таких материалов):

-13

7. Material Function

Еще одна ценная возможность. Это использование материальных функций.

Подход с их применением позволяет упаковать часть функционала в один блок и переиспользовать в основном графе мастер материала неограниченное количество раз:

-14

На примере ниже, я просто умножил FunctionInput (любое входное значение) на 2, и вывел его наружу:

-15

Входное значение - 1

Выходное значение (результат) - 2

Сам механизм (логика) умножающая входное значение на 2

И вот сама функция выглядит в мастер-материале так:

-16

На вход подается скалярное значение равное 2, проходит через саму функцию, в которой это значением преобразуется (помножается на 2) и поступает на выход в атрибут BaseColor. Таким образом на выходе имеем значение 2 * 2 = 4.

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

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

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

-17

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

-18

Регулировка размера текстуры как раз упакована в функцию, в которую в свою очередь подается скалярное значение, определяющее размер текстуры и соответственно ее повторяемость на всей площади ландшафта:

-19

Здесь задается номинальный размер всего ландшафта - 1, который просто делится на некое скалярное значение (оно и определяет тайлинг текстуры на поверхности ландшафта) - 2 и 3.

Этот процесс позволяет как бы поделить весь ландшафт как бы на клеточки, размер которых и задается скалярным значением, после чего результат подается на маску, в которой захватываются только каналы R и G, соответствующие координатам X И Y, исключающие координату Z, что дает возможность более адекватно проецировать ПЛОСКУЮ текстуру на поверхность ландшафта.

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

-20

Давайте рассмотрим более подробно какую-нибудь функцию слоя.

Обратите внимание, здесь для формирования слоя применяется три текстуры -1, текстуры в свою очередь подаются на еще одну функцию, которая включает в работу различные маски и дополнительные параметры для реализации механизма смешивания:

-21

Далее выводится еще одна функция - 2, которая просто за счет компонентных масок отделяет канал в RGB-поле (это нужно на тот случай):

-22

Ну а узел 3 - называется Make material Attribute:

-23

Такой узел нужен для того, чтобы собрать все атрибуты (baseColor, Normal, Roughness и проч.) в единый сигнал и вывести его на узел, определяющий слои (Landscape Layer Blend). Make Material Attribute зачастую работает в связке с противоположным узлом Break Material Attribute:

-24

И после этого, все необходимые сигналы выводятся на выходы функции, т.е. вот сюда:

-25

Таких функций, определяющих слои несколько и они уже поступают на узел слоев Landscape Layer Blend. А дальше, чтобы разбить сигнал снова на атрибуты как раз и подается Break material Attribute, о котором я писал выше:

-26

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

А все дело в том, что между этим двумя процедурами проложен слоевик - Landscape Material Attribute, который задает слои, фактически подматериалы.

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

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

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

-27

Зима:

-28

Общая влажность:

-29

И многие такие компоненты реализованы как раз материальными функциями.

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

-30

Многие особенности материалы мы прошли лишь вскользь.

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

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

Материала очень много и будет очень увлекательно, и полезно!