Меню Рубрики

Unity3d как написать шейдер

Как работать с Shader Graph в Unity3D

Графы шейдеров это новый инструмент для создания шейдеров в юнити. Он позволяет создавать шейдеры людям не имеющим навыков написания кода. Результат каждой операции виден при редактировании. Идеальный инструмент для новичков и экспериментаторов.

Добавление Shader Graph в проект делается при помощи Package Manager.

Но на сегодня доступна версия только для Lightweight Render Pipeline, поэтому для экспериментов нужно создавать проект так:

Простейший шейдер

Shader Graph позволяет создать два вида шейдеров Unlit(без освещения) и PBR(фотореалистичный рендер), а так же sub(нода для шейдера). Последнее можно использовать внутри Unlit и PBR шейдеров.

Unlit не использует встроенных возможностей в юнити по освещнию и затенению модели, только отображает текстуру поверх модели и поэтому с ним намного проще ознакомиться.

Создаём материал и создаём Unlit Graph. Перетягиванием назначаем материалу шейдер.

Открыв шейдер двойным кликом мы увидим мастер-ноду

На выходе этого шейдера мы можем контролировать:

  • Position — позицию вершины
  • Color — цвет каждого пикселя поверхности
  • Alpha — его прозрачность
  • AlphaClipThreshold — порог прозрачности, если мы не используем полупрозрачность

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

Будет ваш шейдер использовать полупрозрачность или нет, можно настроить в мастер-ноде:

  • Opaque — непрозрачный
  • Transparent — полупрозрачный

Чтобы раскрасить модель мы можем подать на вход(color) мастер-ноды трёхмерный вектор или цвет, что для шейдера по сути одно и то же, только по разному отображается в графе.
Новые ноды создаются через контекстное меню

в данном случае мы можем использовать две ноды Color или Vector4

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

а потом мышкой перетянуть его в граф тем самым создав ноду.

  • Exposed — позволяет это свойство видеть в инспекторе при редактировании материала
  • Default — задаёт значение цвета по умолчанию
  • Mode — позволяет выбрать диапазон яркости(HDR позволяет выйти за рамки обычной яркости)

Чтобы созданное свойство влияло на цвет материала надо его выход соединить со входом Color у мастер-ноды.

Самый простой шейдер с текстурой

Чтобы наложить нашу текстуру на меш, нам надо создать ноду, которую можно будет настроить извне Shader Graph. Для этого создадим свойство

и вытянем его, при этом создастся нода текстуры

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

Выход сэмплера соединяем со входом color мастер-ноды

Негатив текстуры

Перед отображением текстуры на экране мы можем её изменить применив математические операции. Например создать негатив простым вычитанием.

Добавим ноду Substract уменьшаемое будет (1;1;1;1), а вычитаемое выходом текстуры.

Смешение двух текстур

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

А саму операцию смешивания произведёт нода Lerp.

Cutout маска

Чтобы сделать полностью прозрачной часть модели нужно подать на вход мастер-ноды значение Alpha канала, создать свойство-слайдер и подать его на вход AlphaClipThreshold

Слайдер нужен для исправления бага в Graph shader, который не позволяет сделать cutout и к тому же он позволит менять значение из настроек материала.

Инверсия UV

Для работы с UV нужно создать ноду UV и подключить её к сэмплеру текстуры

здесь же можно выбрать канал UV, у некоторых моделей этих каналов может быть несколько, на случай многослойных текстур. Этим шагом мы не изменили ровным счётом ничего, а чтобы инвертировать UV, нам нужно создать ноду которая инвертирует значения UV, нам подойдёт обычное умножение на -1 координаты по Y.

Отзеркаливание текстуры можно сделать настраиваемым из материала, для этого нам понадобится нода Branch, она на вход получает булево значение, а на выход одно из двух значений, в нашем случае 1 или -1

Впечатления

Создание шейдера при помощи Shader Graph сильно упрощает задачу хотя бы потому, что можно наблюдать за изменением результата после каждого этапа вычислений. Сам принцип создания через редактор нод позволяет создать что-то новое даже тем, кто ничего не понимает в шейдерах. Инструмент ещё сырой, но уже очень полезный. Так как можно поэкспериментировать в редакторе, а потом воспроизвести созданное кодом, названия функций в большинстве случаев совпадает с названием нод, поэтому Shader Graph может оказаться полезным и программистам.

Источник статьи: http://habr.com/ru/post/435328/

Shader — это не магия. Написание шейдеров в Unity. Введение

Всем привет! Меня зовут Дядиченко Григорий, и я основатель и CTO студии Foxsys. Сегодня хочется поговорить про шейдеры. Умение писать шейдеры (и в целом работать с рендером) очень важно при разработке под мобильные платформы или AR/VR, если хочется добиться крутой графики. Многие разработчики считают, что шейдеры — это магия. Что по ним мало хорошей информации, и что чтобы их писать нужно иметь, как мимимум, звание кандидата наук. Да, разработка шейдеров по своим принципам сильно отличается от клиентской разработки. Но основное понимать базовые принципы работы шейдеров, а так же знать их суть, чтобы в этом не было ничего магического и поиск информации по этой теме был простой задачей. Данная серия статей рассчитана на новичков, так что если вы разбираетесь в программировании шейдеров, данная серия вам не будет интересна. Всем же кто хочет разобраться в этой теме — добро пожаловать под кат!

Это вводная статья в которой я расскажу общие принципы написания шейдеров. Если тема будет интересна, то мы разберём уже подробнее в отдельных статьях: вершинные шейдеры, геометрические шейдеры, фрагментные/пиксельные шейдеры, трипланарные шейдеры, скринспейс эффекты и компьют шейдеры (OpenCL, СUDA и т.п.). И в целом всю ту магию, которую можно делать на GPU. Разбираться это будет в контексте стандартного рендер пайплайна Unity. Так LWRP и HDRP мне пока кажутся немного сыроватыми.

Что такое шейдер?

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

Для понимания того, как работают шейдеры нужно рассказать, что такое графический конвейер (graphic pipeline). Очень часто про эту тему говорят довольно сложными словами, но мы это немного упростим для понимания. Возьмём на примере OpenGL. В этом плане мне очень нравится эта картинка.

Если опустить детали связанные с освещением и т.п. То в целом с точки написания тех же Unlit шейдеров на hlsl суть такова. У нас есть в шейдере

где мы определяем, что вертексная часть шейдера будет писаться в функции vert, а фрагментная — в функции frag.

Структуры которые мы описываем в шейдере определяют какие данные мы будем забирать из меша и после обработки вертексным шейдером, которые висят на нашем MeshRenderer и MeshFilter объекте.

Дальше вертексный шейдер вычисляет получив на вход данные appdata и отдаёт результат в виде структуры v2f, которая дальнейшем пойдёт в фрагментный шейдер. Который в свою очередь уже рассчитает цвет пикселя. Так как информация v2f пишется только в вершины (которых меньше, чем пикселей), данные в фрагментной части интерполируются. Всё это можно представить как то, что vert считается в каждом вертексе независимо. Потом результат передаётся в фрагментную часть, где frag для каждого пикселя считается так же независимо. Так как вычисления производятся параллельно, в данных частях нет никакой информации о соседях (если не передавать её как-то хитро).

Более детально все нюансы, а так же множество примеров описаны в документации Unity docs.unity3d.com/Manual/SL-Reference.html

Языки программирования шейдеров

О чём ещё важно не забывать. О том, что шейдеры сейчас пишутся на трёх языках программирования, которые не имеют никакого отношения к юнити. CG, GLSL и HLSL. Самый простой способ писать шейдеры в юнити — это HLSL, так как именно на нём пишутся файлы шейдеров с разрешением .shader. И если по шейдерам в контексте юнити информации сравнительно мало, то информации отдельно по HLSL, GLSL и CG — просто тонны. В документации к шейдерам описано, каким образом написанное на этих языках перенести в Unity. Поэтому получается что почти вся информация в общем про эти языки программирования валидна. Все три языка очень сильно похожи на язык С, но у каждого свои особенности.

Дальше с точки зрения изучения шейдеров, когда эти языки уже не вызывают вопросов можно посмотреть какие возможности предоставляет сам по себе«UnityCG.cginc» и другие библиотеки написанные юнити, чтобы упростить себе работу.

Почему if в шейдерах — это плохо?

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

Основная идея графических процессоров — это максимальная параллельность вычислений. Тут нужно ввести такое понятие, как “волновой фронт”. По сути оно довольно простое, волновой фронт — это группа шейдеров выполняющая одну и туже последовательность операции. То есть с точки зрения гпу самый лучший вариант, когда в одно и тоже время выполняются одни и те же инструкции. Единственно различие в выполнении — это входные данные. Проблема ветвления в том, что может случиться ситуация, когда в одной группе шейдеров, шейдеры должны вызывать разные операции. Что в свою очередь приводит к созданию нового волнового фронта, копированию в него данных и т.п. А это очень дорого.

Там есть нюансы и исключения, но для того чтобы спокойно писать if, вы должны понимать, как он себя поведёт на целевой версии графического апи. Так как тот же самый OpenGL ES 2 или DX11 в этом плане сильно отличаются.

Зачем мне это знать, ведь есть нодовые редакторы?

Важно понимать, что нодовые редакторы — это в первую очередь инструмент для техникал артистов. Это специалисты, которые имеют экспертизу в математике, но в большей степени являются дизайнерами. Шейдеры типа wireframe (где требуется понимание барицентрических координат) или же преобразование к картезианским координатам, которое используется для хитрых проекций, в разы проще делать кодом, так же как и многие математические модели физических материалов. При этом с точки зрения шейдерного программиста вы по сути делаете кастомные ноды и инструменты для техникал артистов, чтобы творить реальную магию. Нодовые редакторы имеют ограниченный функционал с этой точки зрения. Поэтому важно уметь писать шейдеры на языках типа hlsl. Понимать то, как работает рендер и т.п.

Полезные ресурсы для изучения

С точки зрения изучения шейдерного программирования хорошим упражнением является переписывание шейдеров с www.shadertoy.com или glslsandbox.com. Кроме того существует крутой профиль специалиста из Unity, где можно посмотреть много интересного github.com/keijiro

Всё остальное — это математика и понимание физики эффектов. Это в чём-то похоже на смешивание ингредиентов, если не решается конкретная задача физического моделирования. Много любопытного можно сделать смешивая между собой шум, преломление, подповерхностное рассеивание света, каустику, эффект Френеля, реакцию диффузии и прочие физические свойства объектов. В целом шейдерное программирование это безусловно не элементарно, и там есть куда копать в глубину.

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

Все эффекты в статье — это запись эффектов шейдеров с shadertoy.

Источник статьи: http://habr.com/ru/post/473638/


0 0 голоса
Article Rating
Подписаться
Уведомить о
guest

0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии