Создание интерактивного вершинного эффекта с помощью Shader Graph

Мы создали пример интерактивного эффекта смещения вершин с помощью Shader Graph и Lightweight Render Pipeline, чтобы помочь вам использовать эти возможности для создания эффектов. В этом посте мы расскажем вам о нашем процессе. Получите демонстрационный проект с шейдером Shader Graph, пример сцены и несколько примеров игровых активов из набора 3D Game Kit и следуйте за ним!
Сфера в видео примере ниже имеет эффект смещения на основе шейдера, который активируется, когда мы нажимаем пробел. В вашей игре вы назначите это на какое-нибудь соответствующее игровое событие. В этой статье мы рассмотрим, как создать этот шейдер с помощью пакета Shader Graph и интегрировать в него триггер нажатия клавиши пробела. Цель - помочь вам понять, как создавать эффекты в Shader Graph и взаимодействовать с ними из других скриптов на C#. Демо-проект содержит шейдер, скрипт, управляющий шейдером, предварительно настроенный ассет Lightweight Scriptable Render Pipeline (LWRP) Asset и пример сцены, с которой вы можете начать работу. Если вы предпочитаете просматривать это руководство в виде видео, а не текста, вы можете найти его на канале Unity YouTube.
Сначала давайте рассмотрим, как настроить Shader Graph и Lightweight Render Pipeline. Откройте диспетчер пакетов и выберите установку на пакете Lightweight RP. Это автоматически установит правильную версию Shader Graph.

После установки Lightweight RP нам нужно создать новый актив Pipeline в проекте. Выберите Create->Rendering->Lightweight Render Pipeline Asset.
Затем мы можем активировать этот актив конвейера, перейдя в Edit->Project Settings->Graphics и перетащив LightweightRenderPipelineAsset в поле Scriptable Render Pipeline Settings. Если вы следуете за загруженными активами, этот шаг уже пройден.

Теперь, когда облегченный конвейер рендеринга установлен, мы можем посмотреть, как создать новый шейдерный график. Давайте создадим новый график в нашем проекте, выбрав Create->Shader->PBR Graph. График PBR позволяет нам создать новый шейдер, который получает входные данные от системы рендеринга на основе физики Unity, так что наш шейдер может использовать такие функции, как тени и отражения. После создания шейдера мы добавим его в новый материал и прикрепим материал к сфере в нашей сцене, перетащив материал на сферу.
Чтобы добиться эффекта, мы сместим вершины сетки по нормалям, изменив выходное значение Position в выходном узле PBR Master. Мы будем смещать с помощью узла Add на базовом объекте Position каждой вершины. Добавив вектор нормали к базовой позиции объекта, мы видим, как все вершины становятся экструдированными, в результате чего сфера кажется больше. Чтобы изменить это смещение, мы полуслучайно умножим это нормальное смещение вектора с помощью узла Simple Noise.

Когда мы нажмем кнопку Save Asset, в окне Scene View мы увидим, что сфера теперь смещена на основе Simple Noise.

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

Чтобы создать эффект пульсации, мы прокрутим этот вывод Position, добавив его в узел Time, а затем отправим в узел Simple Noise. Мы также можем использовать Multiply с узлом Time для изменения скорости прокрутки.

Чтобы управлять смещением, мы открываем новое свойство Shader Property в нашем графике шейдеров. Свойства шейдера позволяют нам предоставлять входные данные для нашего шейдера через значения, введенные в инспекторе, или через наши собственные C#-скрипты, как в данном случае. Мы создадим новое свойство Vector1 с именем Amount и изменим Reference на _Amount. Поле ссылки - это строковое имя, по которому мы будем обращаться к смещению и изменять его с помощью скрипта. Если мы не изменим это значение, то будет использоваться автоматически сгенерированное значение. Если строка не совпадает, мы не сможем обратиться к нашему объекту через скрипт, поэтому дважды проверьте, чтобы обе строки совпадали, включая капитализацию.

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

Для управления этой переменной Amount мы создали скрипт на C# под названием DisplacementControl и прикрепили его к игровому объекту DisplacementSphere. Этот скрипт управляет переменной _Amount, взаимодействуя со свойством, которое мы создали в нашем материале и которое назначено компоненту MeshRenderer. Мы сохраняем ссылку на компонент MeshRenderer в переменной meshRender и объявляем новую переменную float displacementAmount.
Мы используем простой lerp в функции Update, чтобы интерполировать переменную displacementAmount до значения 0. Затем мы устанавливаем переменную шейдера _Amount в значение, хранящееся в переменной displacementAmount. Это обновит переменную _Amount графика шейдера, сгладив ее со временем до 0.

Мы используем стандартную ось ввода Unity "Jump" (которая по умолчанию назначена на пробел), чтобы установить значение параметра displacementAmount равным 1 при нажатии.

Теперь, когда мы входим в режим Play Mode в сцене, мы видим, что при нажатии пробела значение displacementAmount устанавливается на 1, а затем медленно интерполируется обратно к 0.
Чтобы создать настраиваемый эффект свечения, мы выведем его на вкладку Emission в узле PBR Master. Мы используем узел Voronoi Noise и умножаем его на узел Color. Это создаст небольшую модуляцию в эффекте свечения с некоторыми темными участками. Затем мы используем узел Lerp с другим узлом Color в качестве базового цвета и используем переменную Amount во входе T. Это позволит нам смешивать базовый узел Color и цветовой узел Voronoi Noise с помощью переменной Amount.

Затем мы прокрутим свечение, используя аналогичную настройку, как и раньше. Мы используем узел Position, установленный на Object, добавляем его к узлу Time и подключаем выход в UV-слот нашего узла Voronoi Noise.



