Создание любых сложных поверхностей 3D-объектов без единой строчки кода!

Если во времена Half-Life 2 в моде были фототекстуры, то сегодня материалы поверхностей в трехмерной графике реального времени воссоздаются с нуля. Это стало возможным благодаря развитию шейдеров — специальных подпрограмм, описывающих внешний вид и устройство поверхностей. За счет современных физически корректных шейдеров поверхности не только имеют правдоподобный рельеф, но еще и взаимодействуют со светом. Благодаря этому, материалы выглядят как настоящие, что еще сильнее приближает 3D-графику к фотореализму.
Так как внутри шейдеров находится программный код, то долгое время для создания материалов требовались навыки программирования. К счастью в UNIGINE 2.15 появился визуальный редактор материалов, позволяющий создавать собственные материалы без необходимости писать код. Он позволяет делать большинство операций простым соединением узлов (нод) в граф. С его помощью можно быстро прототипировать и создавать сложные материалы, а также различные спецэффекты для поверхностей и объектов.
В этой статье расскажем про то, как устроены материалы в UNIGINE 2, а также что такое визуальный редактор материалов, зачем он нужен и как работает.
Как устроены материалы в UNIGINE 2
Материал — это набор свойств (состояний, опций, параметров), ассетов (2D-, 3D-текстуры) и ссылок на шейдеры, описанных в текстовом файле и связанных с конкретной поверхностью объекта.
UNIGINE 2 имеет собственную систему материалов, которая включает в себя:
Базовые материалы, реализованные программистами.
Пользовательские материалы, унаследованные от базовых материалов и настроенные 3D-художниками.

Базовый материал — это нередактируемый набор параметров и текстур, передаваемых шейдерам в нескольких проходах (пассах) при рендеринге. Базовый материал можно использовать только для нод или поверхностей определенного типа. Для всех типов нод в UNIGINE есть готовая библиотека базовых материалов и стандартных шейдеров для имитации практически любых материалов реального мира.
Все материалы перечислены в окне Materials (меню: Windows -> Materials Hierarchy). Базовые материалы находятся на верхнем уровне.
mesh_base — это базовый PBR-материал в UNIGINE с внушительным списком стандартных эффектов и настроек, используемый для мешей.

От базовых материалов мы наследуем Пользовательские материалы, переопределяя их некоторые параметры. Создавая новый материал в Asset Browser, мы выбираем базовый материал, тем самым определяем тип совместимых объектов.


Для удобства материалы можно организовать в иерархию: меняя параметры родительского материала, можно изменить сразу целую ветвь всех дочерних материалов, только переопределенные параметры у «детей» остаются прежними.
Это очень удобно в больших проектах, когда художник подготавливает базовый материал для определенного типа поверхности (скажем, дерево или окрашенный металл), а затем от него наследуются новые материалы, с небольшими изменениями, настраиваемые под объекты.
Хотя UNIGINE 2 имеет богатую библиотеку базовых материалов, в некоторых проектах могут понадобиться кастомные, сложные материалы, со своей логикой. И здесь на помощь придет редактор материалов. Он позволит создать любой кастомный материал.

Технически, базовый материал — это текстовое xml-описание параметров, проходов и шейдеров. Традиционно, только программисты способны написать как материал, так и шейдеры для него. Наш визуальный редактор материалов предоставляет дружелюбный для технических 3D-художников процесс создания материалов и шейдерной логики.
Примеры сложных материалов
Эффект капель дождя, стекающих по поверхности
Силовое поле
Кипение жидкости
Лед
Процедурная плитка
Плавление металла
Растворение объектов
Больше материалов с примерами использования можно найти в специальной подборке в SDK Browser: Samples -> Demos -> Art Samples.
Краткий обзор сэмплов есть на нашем YouTube-канале:
Часть 1
Часть 2
Как работает визуальный редактор материалов
Создадим новый граф материала, щелкнув правой кнопкой мыши в Asset Browser и выбрав Create Material -> Material Graph.

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

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

Материалы для мешей:
Mesh Opaque PBR — материал для непрозрачных поверхностей c поддержкой PBR (физически корректный рендеринг и освещение), рендеринг производится на отложенном проходе (Deferred);
Mesh Alpha Test PBR — PBR Alpha-test материал (с отсечением по альфа-каналу), тоже Deferred;
Mesh Transparent PBR — PBR-материал для прозрачных поверхностей, такие материалы визуализируются на этапе прямого рендеринга (Forward);
Mesh Transparent Unlit — нефотореалистичный материал, Forward;
Decal PBR — PBR-материал для декалей.
Остальные настройки позволяют выбрать используемые базисные пространства, активировать различные функции, такие как эмиссия, тесселляция, и управлять настройками компиляции шейдеров. Подробнее — здесь.
Ноды
Граф материала состоит из нод — функциональных блоков, отвечающих за обработку входных данных. Собирая граф и применяя различную математику, мы определяем внешний вид материала. Кнопка Save сохранит граф и скомпилирует его в материал.
Заметьте: при помощи Ctrl+C и Ctrl+V можно не только копировать целые графы в пределах одного материала или между несколькими, но и делиться с другими разработчиками, ведь копирование графов производится в текстовом формате. Достаточно скопировать полученный текст и вставить в окно редактора материалов, чтобы получить готовый граф.
Нода Material является главной нодой вашего материала. Она предоставляет набор входных графических данных и генерирует материал определенного типа в зависимости от текущих настроек.

К примеру, для PBR-материалов мы можем контролировать Albedo, Metalness, Roughness, Specular, Microfiber и Normal значения — основные значения, определяющие свойства поверхности, знакомые тем, кто уже имел опыт с материалами на основе mesh_base.
Наконец, выход ноды Material соединяется с Final-нодой — основной нодой выходного материала.
Важно! Граф материала может содержать несколько нод Material, но будет использоваться только та, которая подключена к Final-ноде.
Те, кто знаком с конвейером рендеринга, знают, что вертексные шейдеры выполняются для каждой вершины геометрии, а пиксельные шейдеры — для каждого пикселя (другие типы сейчас опустим).
В графе материала это также необходимо иметь в виду (особенно если идет речь о быстродействии), но работает автоматически: логика для свойств материала, имеющих значения в каждом пикселе отрендеренной поверхности (к примеру, цвет Albedo, как и почти все остальные), будет выполняться на этапе пиксельного шейдинга; аналогично, свойства, применимые к вершинам (например, Vertex Offset — смещение позиции вершин), будут просчитаны видеокартой на каждую вершину.
Особая нода Vertex Interpolation позволит выполнить логику в вертексном шейдере и применить к попиксельным значениям через интерполяцию, это может оптимизировать расчет, если вершин многократно меньше, чем число пикселей, которые занимает поверхность.
Пример интерполяции индекса вершин в цвет Albedo:


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

Перетаскивание ребра из входного порта открывает палитру создания ноды с предустановленным фильтром для требуемого типа данных для соответствующего порта.
Текстуры можно перетаскивать прямо из Asset Browser. В этом случае нода Sample Texture с соответствующими настройками будет добавлена автоматически.

Параметры

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

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

К любому входному порту можно подключить только одно ребро, но к выходному порту можно подключить несколько ребер.
Большинство входных портов имеют входное значение по умолчанию.
Адаптеры портов
Адаптер порта — это функция, дающая вам возможность выбирать компоненты данных в произвольном порядке, комбинировать и переупорядочивать их, обеспечивая удобный доступ к элементам и большую гибкость, за счет чего минимизируется излишнее усложнение графа.
Доступные варианты подключения:
= — обеспечивает прямое соединение в случае, если тип ввода может предоставить все необходимые компоненты данных.
При выборе другого варианта создается нода Expression, отвечающая за конвертацию между типами.

Адаптер можно изменить позже, дважды щелкнув выражение и отредактировав поле. Нода Expression позволяет вам писать простые арифметические операции и даже использовать графический API UNIGINE.
Ошибки и предупреждения

Панель Warnings and Errors облегчает поиск проблем в графе, она видна только если таковые присутствуют. Достаточно просто выбрать элемент в списке, чтобы узнать детали и найти проблемную ноду в графе и попытаться ее исправить.
Упорядочивание графов
Иногда, особенно в графах сложных материалов, слишком много пересекающихся ребер делают рабочее пространство похожим на паутину, а поток данных очень трудно понять. Поэтому очень важно научиться упорядочивать графы для улучшения восприятия и облегчения работы с ними.
Для этого в визуальном редакторе материалов UNIGINE 2 существует несколько инструментов: циклы, порталы и подграфы. Далее расскажем про каждый инструмент подробнее.
Циклы (Loops)

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

Двойным кликом на ноде Loop Begin можно открыть окно конструктора цикла и задать в нем переменные, меняющиеся с каждой итерацией цикла, и общее число итераций. Подробности создания циклов смотрите в документации.
Порталы
Портал — это набор специальных нод, включающий один вход (Portal In) и один или несколько выходов (Portal Out), связанных с входом по имени. Порталы служат для уменьшения количества пересекающихся ребер и делают граф более «читабельным».

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

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

Чтобы добавить или отредактировать код в ноде, нужно дважды щелкнуть ноду и откроется окно редактора кода. Можно написать столько функций, сколько нужно, последняя функция в коде будет считаться главной.
* * *
Визуальный редактор материалов — мощный инструмент для 3D-художников. Он не только убирает необходимость навыков программирования, но и делает работу с материалами более удобной. Причем результат виден сразу же при изменении и сохранении графа, что значительно ускоряет итеративность разработки. А для более сложной шейдерной логики всегда можно обратиться к программному коду через специальную ноду Function.
Если вы пропустили предыдущий выпуск рубрики «Технологии UNIGINE 2», рассказывающий про нашу технологию отрисовки облаков, то перейдите по ссылке.