среда, 5 июня 2019 г.

Описание Шаблонов Amplify Shader Editor (ASE)

Вступление

Эта функция позволяет пользователям создавать шейдер ASE из уже существующего, который будет использоваться в качестве базового или Шаблон.
Шаблоны - это обычные шейдеры Unity со специальными тегами ASE, размещенными на ключевых точках. Эти теги написаны как комментарии, поэтому они не влияют на компиляцию шейдера и его поведение по умолчанию. Любой шейдер может быть преобразован в шаблон, и, если данный шейдер имеет несколько проходов, каждый из них представлен своим собственным нодом Output.

Как пользоваться

Создать шейдер


Создать шейдер ASE с использованием шаблонов так же просто, как создать обычный шейдер поверхности . Нажмите правую кнопку мыши в окне Project, выберите Create > Amplify Shader, и в этом меню отобразится список со стандартным шейдером поверхности ASE со всеми доступными шаблонами.

 На данный момент доступны следующие шаблоны:
  • Post-Process
  • Default Unlit
  • Default UI
  • Default Sprites
  • Particles Alpha-Blended
Пользователь может в любой момент поменять, какой шаблон использовать в данный момент, а также вернуться к стандартному шейдеру поверхности. Это можно сделать, нажав выпадающий список Shader Type в текущем окне свойств Output Node.


Параметры, доступные на ноде Output, определяются тем, что было доступно для изменения в шаблоне.

Проверьте Исходный Код Шаблона

Пользователь может в любой момент нажать кнопку « Edit Template» в окне свойств нода Output, чтобы проверить исходный код текущего шаблона.
Обратите внимание, что на данный момент ASE загружает информацию шаблона только при запуске, поэтому любые изменения в шаблоне требуют, чтобы пользователь перезапустил плагин, чтобы он вступил в силу при следующей компиляции вашего шейдера.
Это ограничение будет устранено в будущем обновлении.

Шаблоны Нодов

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

Параметры Шаблонов

Новый нод «Template Parameter» доступен сейчас. Он дает вам доступ к Properties и Global Variables, доступным в текущем шаблоне.
Просто нажмите раскрывающийся список «Parameter» в его окне «Node Properties» или в верхнем левом углу тела нода, чтобы выбрать Property/Global Variable для использования. При выборе параметра он сообщит, выбрано ли Property или Global Variable.

Несколько Templates Parameter нод могут быть размещены на графике шейдеров, каждый из которых имеет одинаковые или разные выбранные параметры.

Обратите внимание, что предварительный просмотр для этого нода доступен только в режиме Material и для Property type parameters.

Шаблоны Vertex Data и Fragment Data

Как и в Template Parameters, редактор Amplify Shader также обеспечивает прямой доступ к данным Vertex и Interpolated.
Нода Vertex Data позволяет пользователям получить прямой доступ к данным вершин, объявленным в структуре, заданной в теле вершинного шейдера в шаблоне.
Аналогично, нода Fragment Data позволяет пользователю получить прямой доступ к данным фрагмента, объявленным через структуру интерполятора в шаблоне, который будет отправлен в функцию фрагмента.

Шаблон Local Var Data

Локальные переменные, объявленные в шаблоне, теперь могут быть доступны через график шейдера через ноду Template Local Var Data. Только локальные переменные, которым предшествует тег / * ase_local_var * / над объявлением, будут перехвачены и доступны на графике.

Создайте свой собственный шаблон

Процесс преобразования шейдера в шаблон довольно прост.

Пример Одного Прохода

Вот простой пример вершинного / фрагментирующего шейдера с однократным проходом, преобразованного в шаблон ASE.


Shader /*ase_name*/ "ASETemplateShaders/DefaultUnlit" /*end*/
{
    Properties
    {
        _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        /*ase_props*/
    }
  
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Cull Off
        /*ase_pass*/

        Pass
        {
            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            /*ase_pragma*/

            struct appdata
            {
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
                float4 texcoord1 : TEXCOORD1;
                /*ase_vdata:p=p;uv0=tc0.xy;uv1=tc1.xy*/
            };
           
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 texcoord : TEXCOORD0;
                /*ase_interp(1,7):sp=sp.xyzw;uv0=tc0.xy;uv1=tc0.zw*/
            };

            uniform sampler2D _MainTex;
            uniform fixed4 _Color;
            /*ase_globals*/
           
            v2f vert ( appdata v /*ase_vert_input*/)
            {
                v2f o;
                o.texcoord.xy = v.texcoord.xy;
                o.texcoord.zw = v.texcoord1.xy;
               
                // ase common template code
                /*ase_vert_code:v=appdata;o=v2f*/
               
                o.vertex.xyz += /*ase_vert_out:Local Vertex;Float3*/ float3(0,0,0) /*end*/;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }
           
            fixed4 frag (v2f i /*ase_frag_input*/) : SV_Target
            {
                fixed4 myColorVar;
                // ase common template code
                /*ase_frag_code:i=v2f*/
               
                myColorVar = /*ase_frag_out:Frag Color;Float4*/fixed4(1,0,0,1)/*end*/;
                return myColorVar;
            }
            ENDCG
        }
    }
}


Доступные Теги

Как можно заметить, есть несколько тегов ASE, разбросанных по коду шейдера. Вот краткое объяснение всех доступных тегов:

ase_name

Этот тег чрезвычайно важен, поскольку именно он позволяет ASE узнать, что этот шейдер необходимо проанализировать как шаблон. Это также показывает, где ASE может внедрить новое имя пользовательского шейдера.
Shader /*ase_name*/ "ASETemplateShaders/DefaultUnlit" /*end*/
Строка между ase_name и end используется в качестве имени по умолчанию при создании нового шейдера с использованием этого шаблона.

ase_props

Этот тег указывает, где находятся текущие свойства шейдера и где ASE может вводить новые. Только свойства, объявленные перед тегом, читаются и становятся доступными для пользователя.
В этом шаблоне будут обнаружены и зарегистрированы два свойства: Sprite Texture и Tint.

ase_main_pass

Этот тег относится к многопроходным эффектам, и пусть ASE до сих пор является основным. Пожалуйста, проверьте секцией Multi-Pass для получения дополнительной информации.

ase_hide_pass

Этот тег относится к многопроходным эффектам и позволяет скрыть проходы или полностью исключить их изменение. Пожалуйста, ознакомьтесь с секцией «Excludind/Hidding Passes» для получения дополнительной информации.

ase_tags

Этот тег указывает, где ASE может вводить новые теги/параметры шейдера.
LEGACY: тег / * ase_tag * / больше не используется в версии ASE v1.4.5 или новее, поскольку шаблон может автоматически определить, где они находятся.

ase_pass

Этот тег указывает, где ASE может вводить новые проходы и/или состояния настройки. Это необходимо для таких нодов, как Grab Screen Color, где в шейдере необходимо объявить Grab Pass.
LEGACY: Тег /*ase_pass*/ является необязательным в версии ASE v1.4.5 или новее, поскольку шаблон может автоматически определить, где разместить объявление Grab Pass.

ase_pass_end

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

ase_pragma

Этот тег указывает, где ASE может вводить новые директивы прагмы и включать файлы. Несколько важных нод, таких как Texture Sampler, требуют, чтобы этот тег работал, поскольку они внутренне используют функции Unity из своей библиотеки.
Помимо внутреннего использования указанными нодами, /*ase_pragma*/ также используется для добавления новых #defines, #include и #pragmas, явно объявленных в подразделе «Additional Defines», «Additional Includes» и «Additional Pragmas» в разделе «Pass» ноды «Output».
Мы настоятельно рекомендуем объявить этот тег ДО тега /*ase_globals*/.

ase_vdata

Этот тег указывает, где данные вершины объявляются и где добавляются новые. Он должен быть установлен в конце структуры данных вершины. Он также отвечает за информирование ASE о типе данных, содержащихся в каждом элементе ».
На этом примере
/*ase_vdata:p=p;uv0=tc0.xy;uv1=tc1.xy*/
Три элемента объявлены в структуре.
float4 vertex : POSITION;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;


Для POSITION отправляемые семантические данные обычно являются позицией вершины, но семантика, такая как COLOR или TEXCOORD #, может использоваться для множества различных целей.
Каждый тип данных объявляется через Data Type = Semantic shortcut используют ; в качестве разделителя между объявлениями.
Вот все типы данных:

Тип данных Описание
p Локальная Позиция Вершины
sp Clip Space Position
c Цвет
n Нормал
t Описание
 uv# Описание
Shortcut Semantic
p POSITION
sp  SV_POSITION
c COLOR
n NORMAL
t TANGENT
 uv#  TEXCOORD0#

Глядя на то, как был объявлен этот тег, мы можем увидеть следующую информацию:

  • p=p: семантическая переменная POSITION содержит локальную позицию вершины
  • uv0=tc0.xy: семантическая переменная TEXCOORD0, наиболее конкретно ее компонент x и y, содержит UV set 0
  • uv1=tc1.xy: семантическая переменная TEXCOORD0, наиболее конкретно ее компонент x и y, содержит UV set 1

ase_interp

Этот тег очень похож на ase_vdata в том, как он объявлен, но теперь он позволяет ASE знать, где объявляется структура интерполяторов.
Он также должен быть установлен в конце структуры данных интерполяторов и отвечает за информирование ASE, какой тип данных содержит каждый элемент.
Требуется дополнительный шаг, когда интерполяторы, которые могут использоваться ASE, должны быть явно объявлены в теге.
Это делается с помощью текущего синтаксиса ase_interp(Min,Max). Все интерполяторы между Min и Max, [TEXCOORD#MIN - TEXCOORD#MAX] считаются доступными для использования. Обратите внимание, что Min может быть не полным интерполятором, а только его частью.
Например. если x и y из TEXCOORD1 используются, вы можете объявить тег как ase_interp(1.zw,7). Таким образом, TEXCOORD1 может использоваться ASE, но только каналами z и w.

Итак, на этом примере
/*ase_interp(1,7):sp=sp.xyzw;uv0=tc0.xy;uv1=tc0.zw*/
два элемента объявлены в структуре.


float4 vertex : SV_POSITION; 
float4 texcoord : TEXCOORD0;

 Мы можем видеть следующую информацию, установленную на теге.
  • ase_interp (1,7): Интерполяторы между TEXCOORD1 и TEXCOORD7 доступны
  • sp=sp.xyzw: семантическая переменная SV_POSITION содержит позицию пространства клипа
  • uv0=tc0.xy: семантическая переменная TEXCOORD0 содержит UV Set 0 на своих компонентах xy
  • uv1=tc0.zw: семантическая переменная TEXCOORD0 содержит UV Set 1 на своих компонентах xy
Кроме того, помимо обычных интерполированных данных, некоторые специальные данные также могут быть помечены как доступные через интерполяторы.

Shortcut Semantic
wn  World Normal
wt  World Tangent
wbt  World Bitangent
wvd  World View Dir
wp  World Position

ase_globals

Этот тег похож на ase_props и указывает, где находятся текущие глобальные переменные и где ASE может вводить новые. Только объявленные глобальные переменные перед тегом читаются и становятся доступными для пользователя.
В этом шаблоне будут обнаружены две глобальные переменные _MainTex и _Color. Поскольку эти глобальные переменные связаны со свойствами, они не будут зарегистрированы, поскольку это уже было сделано тегом ase_props.

ase_funcs

По умолчанию ASE помещает все функции, используемые в шейдере, после объявления глобальной переменной через /*ase_globals*/. Устанавливая этот необязательный тег, он сообщает ASE, что его поведение по умолчанию следует игнорировать, а функции следует размещать над тегом /*ase_funcs*/.

ase_vert_input

Этот тег определяет, где расположены входные параметры функции вершины, поэтому ASE может добавлять дополнительные параметры при необходимости. Например. Узел Switch By Face требует, чтобы переменная типа VFACE была объявлена ​​как входная.

ase_vert_code

Этот тег определяет, где ASE может вставить дополнительный код вершины, созданный входными портами вершины на графике. Необходимо определить два дополнительных параметра: первый определяет тип и имя входного параметра функции, а второй - тип и имя выходного / возвращаемого параметра.
/*ase_vert_code:v=appdata;o=v2f*/
  • v = appdata: данные вершин, полученные из переменной v типа appdata
  • o = v2f: вернуть выходную переменную o типа v2f

ase_vert_out

Этот тег определяет основные точки внедрения кода внутри тела вершины. Эти точки преобразуются в Vertex Input ports на ноде Output.
Port Name и Port Type определяются внутри тега как первый и второй из его параметров. В этом текущем примере будет создан порт с именем Local vertex и типом Float3/Vector3.
Тег должен быть размещен внутри переменной операции и включает в себя саму операцию. Затем эта переменная должна использоваться исходным кодом шаблона.

На этом примере
o.vertex.xyz += /*ase_vert_out:Local Vertex;Float3*/ float3(0,0,0) /*end*/
Тег может изменить o.vertex и таким образом добавить к нему смещение. Если к этому входному порту не подключен ни один узел, сохраняется исходная операция.

ase_frag_input

Этот тег похож на ase_vert_input, но он определяет, где расположены входные параметры функции фрагмента, поэтому ASE может добавлять дополнительные параметры при необходимости.

ase_frag_code

Этот тег похож на ase_vert_code и определяет, куда ASE может вставить дополнительный фрагмент кода, созданный портами ввода фрагмента на графике.
Однако для этого тега определен только один параметр, поскольку фрагмент всегда возвращает цвет. Этот параметр указывает тип и имя параметра интерполятора. <Br /
/*ase_frag_code:i=v2f*/
  • i = v2f: интерполяционная переменная i типа v2f

ase_frag_out

Этот тег похож на ase_vert_out, но он определяет основные точки внедрения кода внутри тела фрагмента. Эти точки преобразуются во Fragment Input ports на ноде Output.
Port Name и Port Type определяются внутри тега как первый и второй из его параметров. В этом текущем примере будет создан порт с именем Frag Color и типом Float4/Vector4.
Тег должен быть размещен внутри переменной операции и должен включать в себя операцию по умолчанию. Затем эта переменная должна каким-то образом использоваться исходным кодом шаблона.

В этом примере:
myColorVar = /*ase_frag_out:Frag Color;Float4*/fixed4(1,0,0,1)/*end*/
Тег может изменить myColorVar, чтобы изменить окончательный цвет фрагмента. Если ни один узел не подключен к входному порту, то сохраняется исходная операция.

ase_dependencies_list

Разрешить добавление шейдерных зависимостей при использовании этого шаблона. Список зависимостей заменит тег при создании финального шейдера.

Subshader / Pass Render State Опции

Чтобы конкретный параметр состояния рендеринга (p.e.Cull Mode) был доступен для изменения на холсте, его необходимо сначала объявить в шаблоне. Никаких специальных тегов для правильной записи не требуется.
Параметры, которые объявлены внутри области Pass, устанавливаются как Pass Properties и будут доступны в разделе Pass на выходном узле. Параметры, которые объявлены в области вложенного шейдера до того, как все ее проходы будут установлены в качестве свойств вложенного шейдера и будут доступны в разделе вспомогательного шейдера ноды Output.
Параметры состояния рендеринга, которые в данный момент фиксируются шаблоном:
  • Blend ModeBlend Operation
  • Cull Mode
  • Color Mask
  • Stencil Operation
  • ZTest Mode
  • ZWrite Mode
  • Depth Offset
  • Sub-Shader/Pass Tags
  • Shader Model
Sub-Shader LOD также фиксируется, но не редактируется из графика ASE.

Вот каждая опция состояния рендеринга, отображаемая для текущего примера.

Как видно из источника шаблона SubShader, теги Render и Cull Mode объявляются, поэтому они доступны в разделе SubShader на выходном узле. В Pass-коде объявляется только Shader Model, поэтому она будет единственной доступной в разделе Pass.

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

Также был создан тег / * ase_all_modules * /, чтобы вместо добавления всех свойств вручную автоматически включать все следующие параметры в свойства Subshader / Pass.

    смесь
    Режим отбраковки
    Цветная маска
    трафарет
    глубина
    Модель шейдера

Обратите внимание, что если какое-либо из этих свойств уже определено в SubShader / Pass, будет использовано их исходное определение.
Multi-Pass

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

Основной узел вывода должен быть выбран, поскольку в многопроходном шейдере создается несколько узлов (по одному на проход). Этот выбранный вывод будет внутренне командовать всеми остальными среди прочего. По умолчанию, если ничего не указано, узел Output, представляющий субшейдер 0 Pass 0, будет установлен в качестве основного узла Output, но пользователь может вручную выбрать другой, объявив тег / * ase_main_pass * / внутри предполагаемого прохода.
Связывание портов Pass / Output узла

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

Возможная ошибка взгляните на эту конфигурацию входного порта:
myColorVar = / * ase_frag_out: Frag Color (2); Float4; _MainColor * / fixed4 (0,0,1,1) / * end * /;

Параметр _MainColor - это идентификатор ссылки, установленный для этого конкретного входного порта фрагмента.

Хотя подграф будет подключен только к главному порту, его код будет сгенерирован для каждого конкретного связанного порта.
Исключая / Скрытые проходы

Проходы могут быть полностью исключены из изменения на ASE или просто находиться в скрытом состоянии. Чтобы исключить проход, тег / * ase_hide_pass * / должен быть установлен поверх его тела, и никакие точки ввода данных вершин или фрагментов не могут быть объявлены. Таким образом, тело Pass будет скопировано из шаблона в конечный полученный шейдер.
Скрытый проход - это тот, который не виден на холсте, но в него может быть введен новый код. Это достигается не только применением тега / * ase_hide_pass * /, но и объявлением точек ввода данных как связанных портов. Таким образом, график, связанный с портом основного канала, также будет анализироваться для каждого из портов невидимого прохода.
Шаблон Multi-Pass Switch

Шаблон Multi-Pass Switch - это узел, специфичный для многопроходных шейдеров, поскольку он передает во время компиляции данные входного порта, соответствующие текущему проходу, анализируемому на его выходе.
Multi Pass Пример

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

В основном мы сосредоточимся только на объяснении конкретных тегов и поведения многопроходных шаблонов.


Shader /*ase_name*/ "WikiExamples/Simple Multi Pass Outline" /*end*/
{
    Properties
    {
        _OutlineWidth( "Outline Width", Float ) = 0.1
        _OutlineColor( "Outline Color", Color ) = (0,0,0,1)
        _MainBodyColor ( "Main Body Color", Color ) = ( 0,0,0,1 )
        /*ase_props*/
    }

    SubShader
    {
        Tags{ "RenderType" = "Opaque" }
      
        Pass
        {
            Cull Front
            Blend Off
      
            Name "Outline"
            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            /*ase_pragma*/

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
                /*ase_vdata:p=p;n=n;uv0=tc0.xy*/
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 texcoord : TEXCOORD0;
                UNITY_VERTEX_OUTPUT_STEREO
                /*ase_interp(0.zw,7):sp=sp.xyzw;uv0=tc0.xy*/
            };

            uniform float4 _OutlineColor;
            uniform float _OutlineWidth;
            /*ase_globals*/

            v2f vert ( appdata v /*ase_vert_input*/ )
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID ( v );
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO ( o );
                o.texcoord.xy = v.texcoord.xy;
                o.texcoord.zw = 0;
                /*ase_local_var*/float3 MyLocalVar;
                /*ase_vert_code:v=appdata;o=v2f*/
                v.vertex.xyz += /*ase_vert_out:Vertex Offset;Float3*/ v.normal*_OutlineWidth /*end*/;
                o.vertex = UnityObjectToClipPos ( v.vertex );
                return o;
            }

            fixed4 frag ( v2f i /*ase_frag_input*/ ) : SV_Target
            {
                fixed4 myColorVar;
                /*ase_frag_code:i=v2f*/
                myColorVar = /*ase_frag_out:Color;Float4*/_OutlineColor/*end*/;
                return myColorVar;
            }
            ENDCG
        }

        Pass
        {
            /*ase_main_pass*/
            Cull Back
            Blend Off
          
            Name "MainBody"
            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            /*ase_pragma*/

            struct appdata
            {
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
                /*ase_vdata:p=p;uv0=tc0.xy*/
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float4 texcoord : TEXCOORD0;
                UNITY_VERTEX_OUTPUT_STEREO
                /*ase_interp(0.zw,7):sp=sp.xyzw;uv0=tc0.xy*/
            };
            uniform float4 _MainBodyColor;
            /*ase_globals*/

            v2f vert ( appdata v /*ase_vert_input*/ )
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID ( v );
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO ( o );
                o.texcoord.xy = v.texcoord.xy;
                o.texcoord.zw = 0;
                /*ase_vert_code:v=appdata;o=v2f*/
                v.vertex.xyz += /*ase_vert_out:Vertex Offset;Float3*/ float3( 0,0,0 ) /*end*/;
                o.vertex = UnityObjectToClipPos ( v.vertex );
                return o;
            }

            fixed4 frag ( v2f i /*ase_frag_input*/ ) : SV_Target
            {
                fixed4 myColorVar;
                /*ase_frag_code:i=v2f*/
                myColorVar = /*ase_frag_out:Color;Float4*/_MainBodyColor/*end*/;
                return myColorVar;
            }
            ENDCG
        }
        /*ase_pass_end*/
    }
    CustomEditor "ASEMaterialInspector"
}


Имя шейдера

Прежде всего, обратите внимание на имя шаблона шейдера, которое находится между тегами /*ase_name*/ и /*end*/. Это не только определяет имя шейдера по умолчанию, но и способ его отображения в меню «Create» и в раскрывающемся списке «Shader Type». Таким образом, WikiExamples/Simple Multi Pass Outline будет переведен на это через пункт меню Create: 


Количество Нодов Output 

Вот недавно созданный шейдер, использующий этот шаблон:

Как указано выше, каждый проход будет представлен собственным выходным узлом. Для этого шаблона объявлено два прохода, поэтому будут созданы два выходных узла.
Имя каждого выходного узла задается соответствующим именем прохода. Для первого прохода мы можем видеть его имя, объявленное через Name "Outline":


Pass
{
    Cull Front
    Blend Off

    Name "Outline"
    (...)
}

Что касается второго прохода, его имя объявляется через строку Name «MainBody».

  Pass
{
    /*ase_main_pass*/
    Cull Back
    Blend Off
  
    Name "MainBody"
    (...)
}


Если имя не задано, генерируется внутреннее имя, т. Е. SubShader 0 Pass 0, SubShader 0 Pass 1 и так далее.

Основной Выход


Хотя создано несколько выходных узлов, один из них должен быть назначен основным (и управлять ими всеми). Это визуально представлено значком
.
Возвращаясь к исходному шаблону Main Body, показанному выше, мы можем увидеть тег / * ase_main_pass * /. Это позволяет ASE знать, что основной вывод был выбран как основной.

Связывание Портов


Для демонстрации давайте свяжем оба порта Color. Для этого на первом проходе мы заменим объявление Color фрагмента:

myColorVar = /*ase_frag_out:Color;Float4*/_OutlineColor/*end*/;

от:

myColorVar = /*ase_frag_out:Color;Float4;_Color*/_OutlineColor/*end*/;


Также на втором проходе мы заменим:

myColorVar = /*ase_frag_out:Color;Float4;*/fixed4 ( 1,1,1,1 )/*end*/;

от:

myColorVar = /*ase_frag_out:Color;Float4;_Color*/fixed4 ( 1,1,1,1 )/*end*/;

Каждый входной порт Color теперь использует Id _Color и сообщает ASE, что они связаны. Обратите внимание, что он исчезнет из выходного узла Outline.


Теперь график, подключенный к порту Color ноды MainBody, также будет доступен для невидимого порта Color у ноды Outline.

Под капотом

Давайте подробнее рассмотрим скомпилированный шейдер с использованием шаблонов и сравним его с выбранным шаблоном. Простой пример был создан для демонстрационных целей с использованием шаблона Unlit Template, описанного на примере Single Pass.



В этом простом шейдере цвет выбирается из уже существующего свойства шаблона 2D Sampler, и из него вычисляется значение яркости. Затем между значением яркости и исходным цветом применяется lerp, используя недавно созданное свойство Float под названием Amount в качестве интерполятора.

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



  •  Размещается обычный заголовок Made with Amplify Shader Editor, а имя ase_name заменяется новым именем пользователя My Shader.
  • Тег ase_props заменяется вновь созданным свойством Amount.
  • Поскольку новые теги не были добавлены, они остаются без изменений.
  • Поскольку новые проходы не были добавлены, ase_pass был только удален.
  • Поскольку новые прагмы не были добавлены, ase_pragma была удалена.
  • Поскольку новые данные вершин не были добавлены, ase_vdata была удалена.
  • Поскольку новые интерполяторы не были добавлены, ase_interp был удален
  • Тег ase_globals был заменен объявлением переменной _Amount. Также была объявлена ​​переменная _MainTex_ST, которая будет использоваться для вычисления координат текстуры.
  • Поскольку новые параметры функции вершины не были добавлены, ase_vert_input был удален.
  • Поскольку новые вершинные инструкции не были добавлены, ase_vert_code был удален.
  • Поскольку входной порт локальной вершины не подключен, ase_vert_out удаляется, но он сохраняет значение float3 (0,0,0) по умолчанию, назначенное операции o.vertex.xyz +=
  • Поскольку новые параметры функции фрагмента не были добавлены, ase_frag_input был удален.
  • Тег ase_frag_code был заменен всем необходимым кодом для выборки текстур, применения функции Luminance и создания результата Lerp.
  • Поскольку цвет ввода Frag Color подключен, ase_frag_out удаляется, а значение по умолчанию заменяется новым результатом lerp.

Параметры шаблона


Начиная с ASE v1.6.2 rev 01, пользователи смогут добавлять параметры в свойства выходного узла напрямую через шаблоны. Они могут быть объявлены либо в начале тела прохода, либо в теле подшейдера, в зависимости от того, где пользователь хочет, чтобы опции отображались над секциями прохода или подшаблона. Опции подшейдера должны быть такими, которые будут влиять на поведение нескольких проходов, так как опции прохода должны влиять на текущий, где они были объявлены.


Основная структура блока опций определяется следующим образом:


/*<ASE Options Type>: <General Config>
<Options Block>
*/



ASE Options Type


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

  • ase_subshader_options:
    • Опции появляются на главном выходном узле, который будет использоваться всеми проходами.
    •  Опции появляются на главном выходном узле, который будет использоваться всеми проходами.     

  • ase_pass_options:
    • Опции появляются на главном выходном узле, который будет использоваться всеми проходами.
    • Следует использовать поверх тела Subshader.

General Config


Общая конфигурация над блоком опций.

  • CopyOptionsFromMainPass:
    • При добавлении этого флага все параметры текущего прохода переопределяются параметрами основного выходного узла.      
  • Id:
    • Укажите уникальный идентификатор для блока параметров.
    • Id = <Int>
  • Name:
    • Укажите имя блока параметров, как оно будет отображаться в пользовательском интерфейсе параметров нода.
    • Name = <Имя>

Options Block


Все опции и что они делают, объявлены над этим блоком.
Option,<Option Id>:<Option Name,Config Flags>:<Available Values>:<Default options>

  • Option Id: глобальный идентификатор для этого конкретного блока. Это может быть использовано другими другими опциями, чтобы включить/отключить его.
  • Option Name: имя для текущей опции. Будет использоваться в качестве метки над элементом пользовательского интерфейса ASE.
  • Config Flags
    • InvertActionOnDeselection: Когда выбран параметр, выполняются действия, отмененные последним параметром.
  • Available Values
    • Перечислите все доступные элементы значений, которые будут отображаться либо в виде раскрывающегося списка, либо в виде переключателя.
      • Все параметры должны быть разделены запятой (,).
        • Если доступные параметры указаны следующим образом - Параметры: true, false - тогда создается виджет переключения (с учетом регистра).
        • Другие перечисления элементов опций создадут выпадающий виджет.
  • Default options: элемент параметра, который будет выбран по умолчанию, когда пользователь выбирает шаблон.

Port:<Pass Name>:<Port Name>


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



  • Pass Name: это нужно указывать только в том случае, если этот блок объявлен в теле подшейдера.
  • Port Name: имя идентификатора порта, который будет проверяться.

  • <Option Selection>:<Action Type>:<Optional Pass Name>:<Action Setup>

    Они вызываются Actions aи связаны с выбранными параметрами. Выбор может запускать несколько действий, а также действие может быть связано с несколькими вариантами.

    • Option Selection: выбор параметра, который будет связан с текущим действием. Можно добавить несколько вариантов, каждый из которых отделяется запятой (,).
    • Action Type: Тип действия, которое будет установлено. Вот доступные действия
      • ShowOption: показывает параметр над разделом, который был создан.
      • HideOption: скрывает параметр над разделом, в котором он был создан.
      • SetOption: устанавливает значение для определенной опции.
      • ShowPort: показывает входной порт от определенного выходного узла.
      • HidePort: скрывает входной порт от определенного выходного узла. Все подключения к нему будут удалены.
      • SetPortName: переименовывает входной порт из определенного выходного узла.
      • SetDefine: устанавливает директиву #define для одного или всех проходов.
      • RemoveDefine: удаляет директиву #define из одного или всех проходов.
      • SetUndefine: устанавливает директиву #undef для одного или всех проходов.
      • RemoveUndefine: удаляет директиву #undef из одного или всех проходов.
      • ExcludePass: исключает определенный проход из написанного в финальном шейдере.
      • IncludePass: включает в себя определенный проход, который будет записан в финальном шейдере.
      • SetPropertyOnPass: устанавливает определенное свойство на конкретном проходе.
      • SetPropertyOnSubShader: устанавливает определенное свойство для текущего подшейдера.
    • Optional Pass Name: эта необязательная информация устанавливается, если это действие устанавливается в опции для определенного прохода. Если опция устанавливается для субшейдера, возможно, потребуется указать пароль.
    • Action Setup: это будет напрямую зависеть от самого действия и будет иметь всю информацию, необходимую для его настройки.
        • ShowOption: Option Name
        • HideOption: Option Name
        • SetOption: Option Name,Option Value
        • ShowPort: Input Port Name or Input Port Unique Id
        • HidePort: Input Port Name or Input Port Unique Id
        • SetPortName: Input Port Unique Id,New Input Port ame
        • SetDefine: Define value ( without the #define keyword )
        • RemoveDefine: Define value ( without the #define keyword )
        • SetUndefine: Define value ( without the #undef keyword )
        • RemoveUndefine: Define value ( without the #undef keyword )
        • ExcludePass: Pass Name
        • IncludePass: Pass Name
        • SetPropertyOnPass: Property Type(listed below),Value(s)
        • SetPropertyOnSubShader: Property Type(listed below),Value(s)
          • CullMode: Cull value
          • ColorMask: R(true/false),G(true/false),B(true/false),A(true/false)
          • ZWrite: Z Write value
          • ZTest: Z Test value
          • ZOffsetFactor: Z Offset Factor value
          • ZOffsetUnits: Z Offset Units value
          • BlendRGB: Blend RGB Source Value, Blend RGB Dest Value
          • BlendAlpha : Blend A Source Value, Blend A Dest Value
          • BlendOpRGB: Blend Op RGB value
          • BlendOpAlpha: Blend Op Alpha
          • StencilReference: Stencil Reference value
          • StencilReadMask:Stencil Read Mask value
          • StencilWriteMask: Stencil Write Mask value
          • StencilComparison: Stencil Comparison value
          • StencilPass: Stencil Pass value
          • StencilFail: Stencil Fail value
          • StencilZFail: Stencil ZFail value
          • RenderType:Render Type value
          • RenderQueue: Render Queue value,Optional Offset

    Пример

     Вот простой пример, используемый над шаблоном Unlit.

    /*ase_subshader_options:Name=Additional Options
        Option:Vertex Position,InvertActionOnDeselection:Absolute,Relative:Relative
            Absolute:SetDefine:ASE_ABSOLUTE_VERTEX_POS 1
            Absolute:SetPortName:1,Vertex Position
            Relative:SetPortName:1,Vertex Offset
    */



    Этот фрагмент объявлен в самом начале шаблона subhader и создает блок опций с именем Additional Options. Внутри этого блока создается опция Vertex Position, которая будет иметь два возможных значения, Absolute и Relative, причем, последнее является значением по умолчанию. После этого к каждому действию добавляются его возможные значения. Для Absolute добавляется #define ASE_ABSOLUTE_VERTEX_POS 1 для того, чтобы только проход был доступен, а для входного порта с Unique Id 1 его Name set to Vertex Position. Для Relative, у входного порта с Unique Id 1 его Name set to Vertex Position.

    Теперь есть маленькая деталь. Поскольку используется флаг InvertActionOnDeselection, для каждого из них будет выполнено противоположное действие, если его значение не выбрано. Для SetPortName нет противоположного действия, но для действия SetDefine есть противоположный RemoveDefine. Таким образом, когда выбрано Relative значение (Absolute отменен), будет выполнено действие RemoveDefine:ASE_ABSOLUTE_VERTEX_POS 1

    Чтобы получить более полный пример параметров шаблона, проверьте шаблон HD Lit, упакованный внутри пакета AmplifyShaderEditor > Plugins > EditorResources > Templates > SRP > HDSRPTemplates.unitypackage package.

    Примеры

    Пожалуйста, проверьте папку AmplifyShaderEditor > Examples > Official > TemplateExamples в вашем пакете Amplify Shader Editor для примеров, использующих каждый из доступных шаблонов.

    Комментариев нет:

    Отправить комментарий

    Примечание. Отправлять комментарии могут только участники этого блога.