ИгрыХабрахабр

[Перевод] Стильный водопад из RiME в игровом движке: делаем водяной поток

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

Вы, возможно, удивитесь: зачем так много полигонов?
Начнем с очевидного — берем обычный Panner и меш. А чтобы это выглядело красиво, нам понадобятся дополнительные вершины. Как и в водопаде Саймона, я использую vertex displacement для смещения вершин модели в 3D-пространстве через шейдер. Для оптимизации можно создать LOD-меши (Level Of Detail) с меньшим количеством полигонов, и заставить Unity переключаться на модели с более низким разрешением.

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

Одна сторона UV shell привязана к 0 по направлению U, а другая к 1. Как и в случае меша кругов на воде, UV-развертка должна быть с наименьшим количеством швов на модели при использовании тайлинговых текстур. Если мы будет тайлить 1,2 раза в направлении U, то на стыке появится шов. Помните, что по ширине UV shell должен укладываться в целое значение U-пространства (например, тайлинг 1, 2 или 3). А нам нужна бесшовная тайлинговая текстура.

Заметьте, как правая часть 3D-изображения идеально попадает в 1 по U-направлению. Так выглядит карта нормалей тайлингованная 3 раза по U-направлению. Установка тайлинга равным 3 по направлению U означает, что текстура повторяется 3 раза между 0 и 1 в направлении U (на изображении ниже показано UV-пространство от 0 до 1).

Для многих это очевидно, но важно понять, почему и как вы должны размещать свои UV-развертки в определенных сценариях. Для примера вот та же текстура тайлингованная 2,2 раза — сразу появился шов. Мы работаем с панорамированием тайлинговых текстур и к тому же нам не нужны швы, поэтому должны адаптировать UV-развертку.

У одной ширина UV shell составляет ровно 1 (прекрасно тайлится), другая урезана так, чтобы был виден шов. Чтобы картина была более полной, посмотрите на гифку, где я перемещаю UV-карту. Поскольку мы используем только тайлинговые текстуры, UV-карта не обязательно должна быть в пределах от 0 до 1.

Поэтому при использовании Panner текстура движется быстрее или медленнее в определенных точках меша. У водопада (как и с кругами на воде) я тоже исказил UV-карту. Попробуйте включить soft selection для искривления UV — так получаются более плавные переходы. Дополнительные полигоны в этом случае делают переход между искаженными участками менее заметным.

Всегда представляйте себе переход с UV на 3D. Обратите внимание, как текстура сильнее растягивается на изгибе водопада — этот эффект можно по-разному регулировать. Если переместить UV-вершины дальше друг от друга, текстура будет появляться чаще на этой области меша и медленнее перемещаться в 3D-пространстве при использовании Panner. Чем ближе друг к другу вершины UV, тем быстрее текстура будет перемещаться по этим UV в 3D-пространстве при использовании Panner. Экспериментируйте, пока не получите желаемый эффект.

Создайте новый материал и нанесите на него новый шейдер (смотрите часть 1).
Примечание: это новый материал.

Добавим их друг на друга, чтобы получить ощущение более случайного эффекта. Мы снова используем одну текстуру с несколькими вариантами скорости/направления Panner, также как и тайлинга UV (флипнем один из них, придав отрицательное значение U). И используем их аутпут для добавления множества других настроек: opacity, color variation и vertex displacement.

Только одну, потому что она так быстро движется с двумя Panner для варьирования, что разницы в данном случае не будет. Также я использовал прокрутку карты нормали. В результате слишком насыщенная карта нормалей стала более ровной и спокойной. Умножим его на значение синего равным 1 (на гифке указано 255 — это то, когда у каждого канала есть 256 шагов, от 0 до 255), а также на значения красного и зеленого равными 60 (или значение 0,23, если вы используете шкалу от 0 до 1). Так вы получите чуть больше настраиваемости внутри самого шейдера. Чтобы вернуть более интенсивные нормали — сохраняйте одинаковыми значения R и G и увеличивайте их.

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

Видно, что здесь используется тип прозрачного кат-аут рендеринга — водопад полностью непрозрачный или полностью прозрачный. На ней поток воды прокручивается по 3D-мешу и разрывается внизу. Тут же заметен и vertex displacement, о котором мы говорили ранее. Вода меняет цвет, когда приближается к земле, и выглядит менее гладкой на белых участках. Теперь подробнее — начнем с цвета. Все эти факторы придают водопаду более живой и натуральный вид.

Эта текстура в основном служит маской для выбора — показывать синий или белый цвета. Я использую Lerp (линейная интерполяция) с двумя цветами и прокручивающуюся черно-белую текстуру, которую сделали в начале, в качестве альфы (входного сигнала). А Add подключается к vertex color node (ноду с цветами вершин).

Они работают подобно vertex colors из первой части — то есть как градиент. Ниже показаны использованные vertex colors. Поскольку мы добавляем vertex colors поверх уже имеющегося цвета (самая белая точка vertex color = 1), можно легко превысить значение 1. Цвета нужны, чтобы убедиться, что вода становится белее к нижней части водопада. Поэтому в конце стоит Clamp, чтобы максимальные значения не превышали 1 (у Clamp минимальное = 0, а максимальное = 1). Если это произойдет, то мы получим слишком яркие и перенасыщенные результаты. Чем светлее vertex color, тем больше вершин выпирают наружу. Использование белого и синего цветов гарантирует, что при «разрыве» воды, она окажется в белой (вспененной) области меша и получит белую границу вокруг прозрачных областей. Изгиб водопада тоже немного светлее — отсюда его скорость. Таким образом, конец водопада, который светлее по vertex color, движется более хаотично.

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

Fresnel делает пиксель настолько светлее, насколько вектор нормали на поверхности 3D-объекта отклонен от камеры и настолько темнее, насколько вектор нормали направлен в камеру (перпендикулярен камере). Дополнительно подключаем fresnel в канале emission для создания фейкового света, который проходит сквозь воду.

При этом нельзя, чтобы водопад светился — для ослабления эффекта я использовал min node. Если посмотреть под углом, то водопад становится более «тонким» — здесь пригодится fresnel, чтобы показать больше фейкового света в этих зонах. Подключение 0 (черный) к emission ничего не даст, а подключение 1 (белый) сделает его un-lit шейдером, который будет выглядеть полностью освещенным со всех сторон (даже если он будет находиться в тени). Fresnel часто используется с шейдерами воды для изменения цвета в зависимости от угла обзора.

Если вы проскроллите немного выше, то увидите, что vertex color светлые снизу и темные сверху. Для придания гладкости я флипнул vertex color, используя one minus node. Более темные значения равны менее гладкой поверхности, а более светлые значения — более гладкой. Перевернув их (чтобы стало светло сверху и темно снизу), можно сделать нижнюю часть водопада менее гладкой по сравнению с верхней.

Смещая вершины, водопад выглядит менее статичным и соответственно более живым. Vertex displacement или vertex offset — важная штука, необходимая для реализации этого эффекта.

Это водопад без vertex displacement:

А вот с vertex displacement:

Если направить значение 0,5 в аутпут vertex offset главного нода, то ничего не случится. Перемещая вершины на основе нашей прокручивающейся черно-белой текстуры, водопад становится плавнее. Все, что ниже 0,5, будет двигаться в отрицательном направлении, а все, что выше 0,5 — в положительном. Постарайтесь держать серый цвет со значением 0,5 в качестве стандартного значения вершины.

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

Отрицательное направление будет означать, что вершина движется «внутрь» относительно направления нормали вертекса на поверхности, а положительное направление будет двигаться «наружу». В нашем случае мы хотим отодвинуть вершины от поверхности меша. Каждая вершина, даже если она является всего лишь одной «точкой» в 3D-пространстве, имеет назначенное ей направление — vertex normal. Для именно такого движения вершин мы можем использовать vertex normals. В этом примере я сделал шар и задал в Maya отображение vertex normals (display > polygons > vertex normals). Оно используется для вычисления того, как поверхность меша должна быть затененна. Также можно редактировать любую vertex normal и изменять ее направление, но сейчас текущее нас устраивает. У каждой вершины есть направление, которое по умолчанию указывает на расстояние от поверхности. Теперь можно использовать его в шейдере и указать, в каком направлении сместить вершины.

В шейдерах и с нормалями в целом значения RGB используются для выражения 3D-объекта координат XYZ в 2D-пространстве. Vertex normal node выводит значения RGB, которые основаны на направлении нормали вершин меша. Я добавил vertex color в вершины, чтобы низ меша стал более выпуклым. Для того, чтобы наш черно-белый Panner в шейдере мог перемещаться вдоль поверхности 3D-объекта, мы можем использовать значения RGB vertex normal. А также несколько нод для контроля величины смещения (это нормально, если ваши значения будут ниже 0 или выше 1).

Для демонстрации приведу сферу с vertex normal node, примененного непосредственно к альбедо (цветному) аутпуту главного нода.

Вывод RGB (XYZ) vertex normal node основан на vertex normals меша, что дает нам такой результат.

На ней видно, где и как все соединяется. Вот полная структура нодов.

Моя цель была в том, чтобы дать достаточное количество знаний и отправных точек для самостоятельного создания подобного водопада. Надеюсь, вы для себя узнали что-то новое. Конечно, я не только что открыл Amplify и создал этот эффект одним махом — были и другие попытки, которые не сработали. Чтобы делать такие вещи, не обязательно знать всё — достаточно базовых вещей.

Еще несколько полезных ссылок по теме:

  • Доклад Джулиана Лава, который работал над Diablo в качестве VFX-художника. Выступление в основном касается навыков в эффектах, но многие из показанных вещей применимы и к другим типам realtime VFX.
  • Блог Little Chicken Game Company. Он посвящен созданию игрового арта без текстур и интересным техникам для создания красивого окружения.
  • У моего вдохновителя Саймона Трюмплера есть много других интересных вещей на сайте. Одна из моих любимых — страница с так называемыми Game Art Tricks.
  • YouTube-канал с роликами о шейдерах. Мои любимые — те, в которых воссоздают специфические эффекты из игр (в Unity).
Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть