image

Шейдер — это небольшая программа, содержащая инструкции для GPU. Она описывает способ вычисления экранного цвета для определённого материала.

Хотя у Unity есть Standard Shader, иногда требуется реализовать эффект, на который не способен стандартный шейдер.

Раньше для этого необходимо было знание особого языка шейдеров, такого как Cg или HLSL, а подходы в них немного отличаются от обычного создания скриптов геймплея. Для многих людей написание шейдеров — это непопулярная сторона разработки игр, потому что требуется освоение дополнительной кривой обучения.

В Unity появился Shader Graph, позволяющий упростить написание шейдеров почти без кода. Лучше всего то, что Shader Graph позволяет работать с визуальным интерактивным интерфейсом.

В этом туториале вы создадите свой первый шейдер для Unity!

Приступаем к работе


В этом туториале используется Unity версии 2019.1 или более новая. Скачать новую версию Unity можно здесь.

Примечание: хотя этот туториал предназначен для новичков в Shader Graph, в нём предполагается, что вы знаете основы разработки в Unity и освоили интерфейс движка. Если вы новичок в разработке на Unity, то изучите отличный туториал Getting Started In Unity.

Скачайте материалы туториала по ссылке. Затем распакуйте содержимое и откройте Intro to Shader Graph Starter в Unity.

Папка RW в окне Project упорядочена следующим образом:

  • Fonts: шрифты, используемые в сцене.
  • Materials: материалы для сцены.
  • Models: 3D-меши для игровых фигур и фона.
  • PostFX: эффекты постобработки для рендеринга сцены.
  • Prefabs: различные заранее созданные компоненты.
  • Scenes: игровая сцена.
  • Scripts: скрипты с игровой логикой.
  • Shaders: графы шейдеров, созданные для этого туториала.
  • Sprites: спрайт, используемый как часть инструкций.
  • Textures: текстурные карты для игровых фигур и фона.

Теперь загрузите сцену TangramPuzzle из папки Scenes.


Это простая игра под названием «танграм», появившаяся в 19 веке в Китае. Задача игрока — переместить семь плоских геометрических фигур, составив из них стилизованные пиктограммы или силуэты.

Запустите режим Play в редакторе и протестируйте демо игры.

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

Сможете разобраться, как переместить семь фигур, чтобы составить такие паттерны?


Итак, с технической точки зрения игра работает, но она не даёт никакой визуальной обратной связи о выбранной фигуре.

Что если мы сможем заставить фигуру светиться, когда на неё наводят мышь? Это позволит улучшить интерфейс пользователя.


И это отличный шанс продемонстрировать возможности Shader Graph!

Проверяем параметры конвейера для Shader Graph


Shader Graph работает только с относительно новым Scriptable Render Pipeline, то есть с High-Definition Render Pipeline или с Lightweight Render Pipeline.

При создании нового проекта для работы с Shader Graph выберите правильный шаблон.


Пример проекта уже сконфигурирован для работы с Lightweight Render Pipeline. Сначала подтвердите в PackageManager, что у вас установлены пакеты Lightweight RP и ShaderGraph, выбрав Window ► PackageManager.

Затем выберите одну из доступных версий и при необходимости нажмите кнопку Update to. Обычно наилучшим выбором является последняя verified-версия.


Обновив пакеты, внимательно проверьте правильность параметров конвейера в Edit ► Project Settings.

Во вкладке Graphics параметр Scriptable Render Pipeline Settings должен иметь значение LWRP-HighQuality. Благодаря этому проект будет использовать наивысший параметр по умолчанию для Lightweight Render Pipeline.

Убедившись, что используется один из ассетов Scriptable Render Pipeline, закройте это окно.

Создание PBR Graph


При рендеринге 3D-меша на экран всегда вместе работают материал и шейдер. Поэтому прежде чем приступать к созданию шейдера, нам нужен материал.

Сначала нажмите кнопку Create в окне Project, чтобы сгенерировать новый материал в папке RW/Materials. Выберите Create ► Material, а затем переименуйте его в Glow_Mat.

Затем в папке RW/Shaders создайте PBR Graph, выбрав Create ► Shader ► PBR Graph. Это граф шейдера, поддерживающий физически точный рендеринг, или PBR.

Назовите его HighlightShaderGraph.


Материал Glow_Mat пока использует стандартный для LightweightRenderPipeline шейдер под названием LightweightRenderPipeline/Lit.


Смените его на только что созданный новый граф шейдера. Выбрав Glow_Mat, нажмите на раскрывающееся меню Shader в верхней части инспектора и выберите Shader Graphs ► HighlightShaderGraph.

Материал Glow_Mat приобретёт немного более светлый оттенок серого, но в остальном останется довольно тусклым. Не волнуйтесь, скоро мы это исправим.

Теперь дважды щёлкните на ассет HighlightShaderGraph или нажмите на Open Shader Editor в инспекторе. При этом откроется окно Shader Graph.


Ознакомьтесь с основными частями этого интерфейса:

  • Основное рабочее пространство — это тёмно-серая область, в которой будут храниться операции графа. Можно нажать на рабочем пространстве правой клавишей мыши, чтобы открыть контекстное меню.
  • Нод (node) — это единичный элемент графа. Каждый нод имеет вход, выход или операцию, в зависимости от его портов. Ноды соединяются друг с другом при помощи рёбер.
  • Master node — это последний выходной нод графа. В этом примере мы используем вариант для физически точного рендеринга, также называемый нодом PBR Master. Вы можете заметить в нём отдельные свойства, например, Albedo, Normal, Emission и Metallic, которые используются в Standard Shader.
  • Blackboard может предоставлять доступ к определённым частям графа в инспекторе. Это позволяет пользователю настраивать параметры без непосредственного редактирования самого графа.
  • Main Preview интерактивно отображает текущие выходные данные шейдера в виде сферы.

Соединив различные ноды, вы можете создать граф шейдера, который Unity компилирует и передаёт в GPU.

Создание нода Color


Для начала давайте дадим шейдеру какой-нибудь базовый цвет. Для этого нужно соединить нод цвета с компонентом Albedo нода PBR Master. Нажмите правой клавишей на рабочей области, чтобы создать из контекстного меню первый нод, выбрав Create Node ► Input ► Basic ► Color.


Заметьте, что в меню Create Node есть сотни нодов! Поначалу это кажется запутанным, но вы скоро разберётесь с самыми активно используемыми.

Далее перетащите нод по рабочему пространству, взявшись за его панель заголовка. Затем оставьте его где-нибудь слева от нода PBR Master.

Нод Color позволяет задать одиночный цвет. Нажмите на поле цвета и выберите красивый красный оттенок, например R: 128, G: 5, B: 5.

Чтобы вывести цвет в нод PBR Master, перетащите порт Out в порт Albedo, который обозначает базовый цвет шейдера.

Соединив ноды ребром, вы должны увидеть, как сфера в Main Preview станет красной.


Отлично! В области написания шейдеров создание одноцветного шейдера — это аналог Hello, world!

Хотя вы может быть этого ещё и не поняли, но вы только что создали свой первый шейдер!

Работа с интерфейсом


Хотя в графе есть всего пара нодов, сейчас самое подходящее время освоиться с интерфейсом Shader Graph.

Попробуйте перетаскивать ноды и заметьте, что рёбра между выходным портом Color и входным портом PBR Master остаются соединёнными.

Ноды могут содержать различные типы данных. Так же, как мы создали нод, содержащий единственный входной цвет, можно создать нод, обозначающий одно число; выберите Create Node ► Input ► Basic ► Integer. С этим нодом мы ничего не будем делать, он нужен только для иллюстрации принципа.


Соедините порт Integer Out с портом Alpha нода PBR Master.

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

  • F: выделить рамкой выбранные ноды.
  • A: выделить рамкой весь граф.

Также можно использовать кнопки в верхней части окна, чтобы переключать отображение Main Preview и Blackboard. Кнопка Show in Project помогает найти текущий граф шейдера в окне Project.

Разобравшись с управлением графом, подчистим его. Нам нужны только ноды Color и PBR Master.

Нажмите правой клавишей мыши на соединение между нодами Integer и Master, а затем выберите Delete. Это позволит отделить нод от графа.


Аналогичным образом можно удалить нод Integer целиком. Нажмите правой клавишей мыши на ноде и выберите Delete.


Завершив работу, нажмите на кнопку Save Asset в левом верхнем углу интерфейса. Unity сохранит все изменения, а затем скомпилирует и активирует шейдер. Этот шаг нужно делать каждый раз, когда вы хотите увидеть последние изменения в редакторе.

Теперь вернитесь в окно и выберите материал Glow_Mat.


Так как шейдер распространяется на материал, сфера в окне предварительного просмотра инспектора должна стать красной.

Теперь перетащите материал Glow_Mat на фигуры танграма в окне Scene.


Как и ожидалось, материал с шейдером окрасили меш в красивый однородный красный цвет.

Добавляем эффект свечения


Если вы хотите, чтобы материал Glow_Mat имел более загадочное свечение, то нужно снова отредактировать граф шейдера.

Сейчас выходные данные Color передаются на вход Albedo нода PBR Master.

Можно также перетащить ещё одно ребро из Out к Emission. Теперь тот же цвет используется дважды: и в качестве базового цвета, и в качестве цвета излучения.


Выходные порты могут иметь несколько рёбер, а входные — только одно.

Теперь переключим раскрывающееся меню Mode нода Color в режим HDR. Так мы включим расширенный динамический диапазон цветов.


Теперь изменим поле цвета. В HDR Mode появилась дополнительная опция Intensity. Нажмите пару раз на +1 в нижней палитре или перетащите ползунок примерно на 2.5. Теперь сохраните изменения и вернитесь в редакторе.


В редакторе фигура начнёт светиться ярко-оранжевым цветом. Постобработка в сцене уже включена и она усиливает цвет расширенного динамического диапазона.

Теперь выберите в иерархии game object PostProcessing. Свечение возникает благодаря эффекту Bloom.

Откройте параметры Bloom и настройте Intensity (силу свечения) и Threshold (порог начала свечения). В примере показаны значения 3 и 2.


Ого, вот это сияние!


Создание скрипта подсветки


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

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

Сначала создадим в RW/Scripts новый скрипт на C# и назовём его Highlighter. Он поможет нам переключаться между двумя материалами во время выполнения программы. Замените все строки в скрипте следующим кодом:

using UnityEngine;

// 1
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(Collider))]
public class Highlighter : MonoBehaviour
{
    // 2
    // reference to MeshRenderer component
    private MeshRenderer meshRenderer;

    [SerializeField]
    private Material originalMaterial;

    [SerializeField]
    private Material highlightedMaterial;

    void Start()
    {
        // 3
        // cache a reference to the MeshRenderer
        meshRenderer = GetComponent<MeshRenderer>();

        // 4
        // use non-highlighted material by default
        EnableHighlight(false);
    }

    // toggle betweeen the original and highlighted materials
    public void EnableHighlight(bool onOff)
    {
        // 5
        if (meshRenderer != null && originalMaterial != null && 
            highlightedMaterial != null)
        {
            // 6
            meshRenderer.material = onOff ? highlightedMaterial : originalMaterial;
        }
    }
}

Давайте разберём этот скрипт:

  1. Скрипт может быть применён только к объекту, содержащему компоненты MeshRenderer и Collider. Это контролируется добавлением атрибутов [RequireComponent] в начало скрипта.
  2. Это ссылки на MeshRenderer, originalMaterial и highlightedMaterial. Материалы помечены атрибутом [SerializeField], что позволяет назначать их из инспектора.
  3. В методе Start мы автоматически заполняем MeshRenderer при помощи GetComponent.
  4. Вызывается EnableHighlight(false). Это гарантирует, что по умолчанию будет отображаться неподсвеченный материал. Ниже находится публичный метод EnableHighlight, переключающий материал рендерера. Он получает булев параметр onOff, определяющий состояние подсветки.
  5. Предотвращаем все ошибки NullReference
  6. Для экономии пространства используем тернарный оператор.

Добавляем события мыши


Так как этот скрипт применяется к фигурам, у которых есть MeshCollider, мы можем воспользоваться встроенными методами OnMouseOver и OnMouseExit. Добавим после метода EnableHighlight следующий код:

    private void OnMouseOver()
    {
        EnableHighlight(true);
    }

    private void OnMouseExit()
    {
        EnableHighlight(false);
    }

Когда мышь находится над фигурой, он будет вызывать EnableHighlight(true). Аналогично, когда мышь покидает Collider, он будет вызывать EnableHighlight(false).

Вот и всё! Сохраните скрипт.

Подсветка фигуры


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

Сначала выберем семь объектов внутри transform Tangram, представляющих собой отдельные фигуры. Затем добавим им всем одновременно скрипт Highlighter.


Затем перетащим в поле Original Material материал Wood_Mat, а в поле Highlighted Material — материал Glow_Mat. Теперь запустим режим Play и проверим результат нашей работы.

Неплохо! При наведении курсора мыши на фигуру танграма она начинает светиться ярко-красным цветом. Если убрать от неё курсор, она возвращается к исходному состоянию.


В самой игре ничего не изменилось, но эффект подсветки добавил визуальной интересности и позволяет игроку сосредоточить внимание.

Использование нодов текстур


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

Для начала изменим HighlightShaderGraph, дважды щёлкнув на него или выбрав
в редакторе Open Shader Editor.

Удалим нод Color, щёлкнув на нём правой клавишей мыши и выбрав Delete. Мы будем создавать всё с нуля.

Вместо одного цвета мы подставим текстуру, воспользовавшись нодом Sample Texture 2D.

Создайте нод, или из контекстного меню, нажав правой клавишей мыши и выбрав Create Node, или с помощью горячей клавиши (пробела). Выберите Input ► Texture ► Sample Texture 2D.

Нод Sample Texture 2D считывает информацию цвета из ассета текстуры и выводит его RGB-значения.

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

Выберите ассет текстуры WoodAlbedo.


Соедините выходной порт RGBA нода Sample Texture 2Dс портом PBR Master Albedo.

Вуаля! Теперь на поверхности сферы предварительного просмотра отображается текстура дерева.


Если добавить карту нормалей, то можно создать детали на поверхности. Для начала создадим ещё один нод Sample Texture 2D, выбрав Create Node ► Input ► Texture ► Sample Texture 2D.

Выберите во входном порте Texture текстуру WoodNormal.


Измените в раскрывающемся меню Type тип с Default на Normal.

Выведите значения RGBA в порт Normal нода PBR Master.


Сфера Main Preview теперь должна выглядеть более шероховатой. Карта нормалей имитирует небольшие неровности и углубления на поверхности. Это позволяет имитировать внешний вид дерева.

Примечание: тип данных каждого порта указан в скобках рядом с портом. (T2) означает, что порт совместим с двухмерной текстурой, а (4) означает, что порт использует Vector4. В зависимости от контекста Shader Graph может игнорировать лишние значения с плавающей запятой.

Добавление эффекта Френеля


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

Вместо равномерного свечения всего объекта мы ограничим свечение только его краями. Это можно реализовать при помощи эффекта Френеля.

Создайте новый нод, нажав правую клавишу мыши или пробел, а затем выберите Create Node ► Math ► Vector ► Fresnel Effect.

Этот новый нод демонстрирует сферу с белым сияющим кольцом по диаметру. Можно настроить ширину этого гало при помощи входного порта Power. Щёлкните и перетащите метку X в левую часть поля или введите нужные числа.

Чем больше значения, тем тоньше становится гало, а маленькие значения делают его очень широким. Чтобы создать тонкое свечение по краю, можно использовать значение 4.


Чтобы передать это гало материалу, мы соединим выход Fresnel Effect со входом Emission нода PBR Master.


Теперь в MainPreview отображается деревянная сфера с ярко-белым гало, полученным благодаря Fresnel Effect.

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


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

Умножение на Color


Добавить цвета светящемуся контуру можно при помощи простых вычислений с цветами.

Создайте новый нод цвета, который будет обозначать цвет светящегося кольца. Нажмите правую клавишу мыши или пробел, чтобы открыть контекстное меню, а затем выберите Create node ► Input ► Basic ► Color. Переключите цветовой режим в HDR.

Выберите цвет, который будет обозначать цвет подсветки. Например, выберем красивый яркий зелёный: R:5, G:255, B:5.

Увеличим Intensity до 3.5.


Мы не можем соединить новый цвет к эффекту Френеля. потому что он не имеет входа для цвета. Поэтому нам нужно будет скомбинировать выход эффекта с выходом нода цвета. Это можно сделать при помощи нода Multiply.

Создадим нод Multiply, нажав правую клавишу мыши, а затем выберем Create node ► Math ► Basic ► Multiply.

Удалим ребро между Fresnel Effect и PBR Master. Соединим выход Fresnel Effect со входом A нода Multiply.

Соединим Out нода Color со входом B нода Multiply.


Затем соединим Out нода Multiply с портом Emission нода PBR Master. Вуаля! Теперь мы видим, как ярко-зелёный HDR-цвет окружает сферу Main Preview.


Помните, что можно использовать Fresnel Effect Power для увеличения или уменьшения гало. Если уменьшить значение до 1.5, то получится широкое зелёное сияние.

Для нашего примера игры хорошо подойдёт значение от 4 до 5, но вы можете поэкспериментировать со своими значениями.


Сохраните граф шейдера и вернитесь в редактор. Вы сразу увидите свой HighlightShaderGraph в действии.

Запустите режим Play.

При наведении курсора мыши на фигуру она сохраняет свою текстуру дерева. Однако теперь вокруг её краёв появилось яркое зелёное свечение. Формально в игре ничего не изменилось, только подсветка стала более слабой.


Добавляем свойства Blackboard


Если вы хотите изменить внешний вид эффекта свечения, то нужно вернуться в окно редактора Shader Graph и внести эти изменения. Например, при помощи Fresnel Effect Power расширить или сузить полосу гало.

Это не очень удобно, если мы захотим тестировать различные изменения. К счастью, у Shader Graph есть концепция свойств (Properties).

Можно сделать часть графа публично видимой в инспекторе, что позволит вносить небольшие изменения интерактивно. Это делается при помощи интерфейса Blackboard.

Вернитесь к Shader Graph и включите отображение Blackboard. Если она скрыта, то нажмите кнопку Blackboard в правом верхнем углу.

Добавление свойств Base Texture и Normal Map


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

Нажмите на значок + в правом верхнем углу Blackboard. Выберите в раскрывающемся списке Texture 2D. Элемент должен появиться на Blackboard. Переименуйте его в BaseTexture.


Убедитесь, что поставлен флажок exposed. Если вы раскроете свойство, то оно станет публичным и доступным в инспекторе.


Чтобы добавить свойство к графу, просто перетащите его за метку в рабочее пространство. Оставьте его где-нибудь слева от нода Sample Texture 2D.

Соедините порт BaseTexture со входным портом Texture нода SampleTexture 2D, который подключен к Albedo. Так мы заменим предыдущее заданное значение.

Повторите тот же процесс для Normal Map. Нажмите на значок + и создайте новую Texture 2D. Переименуйте её в Normal Map.

Перетащите свойство в рабочее пространство и присоедините его к Sample Texture 2D для карты нормалей.


Нажмите Save Asset и вернитесь в основное окно редактора.

Выберите материал Glow_Mat и обратите внимание на два новых поля в инспекторе: Base Texture и Normal Map.

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


Выберите для BaseTexture и NormalMap текстуры WoodAlbedo и WoodNormal.

Теперь под светящимися краями будут правильно отображаться текстуры дерева.


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

Добавляем свойства Glow Size и Glow Color


Теперь мы раскроем в Blackboard и другие типы свойств. Например, будет полезно позволить изменять значение Fresnel Effect Power.

Нажмите на значок + в Blackboard и создайте свойство Vector1. Оно обозначает единичный параметр типа float.

Переименуйте его в GlowSize.

Можно ограничивать диапазон значений, вводимых для этого свойства, преобразовав его в ползунок. Переключите Mode на Slider, а затем укажите для Min значение 0.05, а для Max — значение 6, чтобы задать диапазон. Значению Default присвойте 5.


Перетащите свойство GlowSize в рабочее пространство. Соедините выходной порт со входом Fresnel Effect Power.

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


Выберите нод Color, затем нажмите правой клавишей мыши и выберите Convert to Property.

Нод Color преобразуется в свойство цвета в Blackboard, которое больше нельзя будет изменять напрямую в графе. Переименуйте свойство в GlowColor.


Нажмите Save Asset и вернитесь в основное окно редактора.


Выберите в окне Project материал Glow_Mat. Вы должны увидеть что в инспекторе стали доступны ползунок GlowSize и поле GlowColor.


Измените значения материала на свой вкус. Запустите режим Play, чтобы протестировать свою работу.


Теперь у вас есть настраиваемая подсветка, которую можно как угодно изменять!

Куда двигаться дальше


Поздравляю! Теперь вы можете создавать собственные шейдеры с помощью Shader Graph!

Применив собственные творческие способности, вы сами удивитесь, что у вас получится. Хотите создать крутой фантастический лазерный луч или силовое поле? Адаптируйте результат нашей работы в нужный вам шейдер.

Хотя нодов в буквальном смысле существует сотни, этот туториал должен был помочь вам в освоении Shader Graph.

Комментарии (0)