Песнь без пламени: создание материала льда на Unreal Engine 4

Песнь без пламени: создание материала льда на Unreal Engine 4

Технический художник Тайзид Корамбайл (Taizyd Korambayil), работавший в Epic Games, рассказал порталу 80.lv о материалах и настройке реалистичного льда в UE4.

DTF публикует перевод статьи.

В 2015 году я выпустился из Колледжа искусств и дизайна Саванны со степенью бакалавра геймдизайна. С 2015 года работал в Epic Games в команде Engine Content, в основном — руководил исправлением багов и обновлением шаблонных проектов, поставляемых с движком. Мне также довелось немного поработать над Paragon (исправляя баги с артами на картах).

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

С помощью этого инструмента можно сделать практически что угодно. Конечно, бывают исключительные случаи, когда нужно удалить custom-ноды и использовать HLSL, но чаще всего его возможностей хватает. В свою очередь, Substance Designer больше похож на процедурный Photoshop.

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

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

Я решил взять аналоговую цветовую палитру оттенков синего и использовал Adobe Kuler. Цвета смешиваются при помощи масок. Обычно я беру текстуры с паттернами, в редакторе материалов делаю их разнообразнее и «глубже», а потом использую для интерполяции цветов. Результат зависит от множества факторов — непрозрачности, внутренних элементов (subsurface), ракурса и так далее. Думаю, цвета в этот момент могут быть слишком насыщенными — потом художник может откорректировать их, как хочет.

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

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

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

Одной из моих задач была имитация «глубины» модели — я очень хотел уловить это свойство материала. В Unreal есть нод BumpOffset, позволяющий добавить текстурам параллакс-эффект. В итоге я накладывал друг на друга текстуры с отличающимися значениями параллакса и потом совмещал их.

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

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

В материале используется 4-5 текстур. Одна из них служит для «запекания» карты нормалей меша, три других — паттерны в каждом канале, и ещё одна — карта шума нормалей общего назначения. Для генерации узоров я использовал Substance Designer (один или два — нагуглил). На изображениях ниже видно, как текстуры совмещаются.

Этот нод обычно используют для имитирования глубины материала с помощью эффекта параллакса. Вы вводите значение координат (сoordinate value), высоты и отношение высоты (height ratio value). Значение высоты определяет основание или плоскость, относительно которой она меняется. Если установить высоту на 0 и отношение высоты на -1.0, пиксели будут отрисовываться как бы под поверхностью. Если же установить height ratio value на 1.0 — они будут выпирать над поверхностью (что будет выглядеть очень плохо, если задавать не минимальные значения). Есть инструкция по применению нода.

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

Сначала мы создаём скалярный параметр «Master Tiling» — от него будет зависить тайлинг всего материала.

Далее создаём базовый набор настроек, которые будут повторяться для всех текстур, используемых в шейдере. Назначаем скалярный параметр контролировать тайлинг для каждого TextureSample и размножаем его с помощью параметра Global Tiling. Также мы настраиваем нод bumpOffset и его значения.

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

На этом графике показано создание масок поверхности, задающих зоны, в которых пузырьки становятся видимыми.

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

1) Самый верхний слой пузырьков. Применяем их паттерн к каналу текстуры Blue, устанавливаем height ratio value на -0.2, и они появляются прямо под поверхностью.

2) Пузырьки, которые находятся глубже под поверхностью. Сначала мы создаём два скалярных параметра и добавляем их к координатам текстур — это позволит добавлять оффсеты в слои U и V, и результат станет разнообразнее. Затем мы повторяем процедуру и вновь задаём значение тайлинга. Оно должно быть выше, тогда пузырьки будут меньше, что усилит эффект фальшивой глубины. Соотношение высот в ноде BumpOffset устанавливаем в -1.0.

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

Этот раздел графа отвечает за добавление шероховатости (roughness input) материала. Мы повторяем то, что уже делали, и задаём параметры тайлинга с пятнистым паттерном на канале Blue, используя его как маску линейной интерполяции между минимальными и максимальными значениями неровности. Эти значения выставляются как параметры, чтобы их можно было корректировать. Наконец, мы делаем финальную линейную интерполяцию с маской-паттерном трещин из Mask_01 — так у потрескавшихся областей будет иная степень неровности, нежели у остальной поверхности.

Этот граф будет служить roughness-выходом материала. На предпросмотре это будет выглядеть так:

📎📎📎📎📎📎📎📎📎📎