Ввод данных в HLSL
Чтобы передать данные в пользовательский шейдер в High-Level Shader Language (HLSL), создайте struct, который объявляет переменные шейдера и соединяет их с вершинными данными сетки.
Используйте один из следующих методов:
- Включить предварительно построенную вершинную структуру из библиотеки шейдеров Unity.
- Заявление пользовательской вершинной структуры.
Включите предварительно построенную структуру
Unity содержит библиотеку файлов шейдеров High-Level Shader Language (HLSL), которые содержат предварительно построенные HLSL структуры с общими вершинными входами. Дополнительные сведения см. в:
- Методы шейдеров в URP и Преобразование пользовательских шейдеров для совместимости с URP
- Встроенные HLSL конструкции во Встроенные Render Pipeline
Объявление пользовательской структуры
Чтобы объявить настраиваемую структуру вершин, выполните следующие действия:
- В верхней части
HLSLPROGRAMдобавьтеstruct, который объявляет переменные для каждого входа, к которому вы хотите получить доступ из сетки. - В каждом объявлении переменной добавьте семантику, связывающую переменную с данными сетки. Дополнительные сведения о семантике см. в разделе Semantics в документации Microsoft HLSL.
Список семантики см. в HLSL Справочная семантика.
Например:
Shader "VertexInputCustom" {
SubShader {
Pass {
HLSLPROGRAM
...
struct custom_vertex_input {
// Declare a variable for the vertex position, and connect it to the mesh data using the POSITION semantic.
float4 vertex : POSITION;
// Declare a variable for the vertex normal, and connect it to the mesh data using the NORMAL semantic.
float3 normal : NORMAL;
};
...
v2f vert (custom_vertex_input v) {
...
}
ENDHLSL
}
}
}
Если переменная содержит больше компонентов, чем данные сетки, дополнительные компоненты имеют значения 0 для x, y и z и 1 для w. Например, если вы объявляете float4 с TEXCOORD0, значение будет (u, v, 0, 1).
Передача данных от вершинного шейдера к фрагментному шейдеру
Данные, которые вы передаете от вершинного шейдера к фрагментному шейдеру, известные как интерполяторы, имеют ограничения, основанные на целевой платформе и GPU.
Чтобы минимизировать количество используемых интерполяторов, упаковывайте данные в одиночные переменные. Например, объедините два набора координат float2 и UV в одну переменную float4, где x и y содержат первую координату UV, а z и w содержат вторую координату UV.
Добавить пользовательский буфер для унифицированных переменных
DirectX группирует все унифицированные переменные в постоянные буферы. Отображение может быть быстрее, если вы группируете унифицированные переменные в отдельные постоянные буферы в зависимости от того, как часто они меняются.
Для создания постоянного буфера используйте макросы CBUFFER_START и CBUFFER_END Unity. Например:
CBUFFER_START(RarelyUpdatedVariables)
float4 lightPosition;
CBUFFER_END
CBUFFER_START(FrequentlyUpdatedVariables)
float4 colorTint;
CBUFFER_END