Практическое руководство. Проектирование шейдера корпуса
Шейдер корпуса — это первый из трех этапов, которые работают вместе для реализации тесселяции (два других этапа — тесселлатор и доменный шейдер). В этих разделах показано, как спроектировать шейдер корпуса.
Для шейдера корпуса требуются две функции: main шейдер корпуса и функция константы исправлений. Шейдер корпуса реализует вычисления на каждой контрольной точке; Шейдер корпуса также вызывает константную функцию patch, которая реализует вычисления для каждого исправления.
После создания шейдера корпуса см. статью Практическое руководство. Создание шейдера корпуса , чтобы узнать, как создать шейдер корпуса.
Проектирование шейдера корпуса
Определите контрольные и выходные контрольные точки шейдера оболочки.
// Input control point struct VS_CONTROL_POINT_OUTPUT { float3 vPosition : WORLDPOS; float2 vUV : TEXCOORD0; float3 vTangent : TANGENT; }; // Output control point struct BEZIER_CONTROL_POINT { float3 vPosition : BEZIERPOS; };
Определите выходные данные констант исправления.
// Output patch constant data. struct HS_CONSTANT_DATA_OUTPUT { float Edges[4] : SV_TessFactor; float Inside[2] : SV_InsideTessFactor; float3 vTangent[4] : TANGENT; float2 vUV[4] : TEXCOORD; float3 vTanUCorner[4] : TANUCORNER; float3 vTanVCorner[4] : TANVCORNER; float4 vCWts : TANWEIGHTS; };
Для четырехдоменного домена SV_TessFactor определяет 4 фактора тесселяции ребер (для тесселирования ребер), так как тесселлятор фиксированной функции должен знать, сколько тесселяции нужно выполнить. Необходимые выходные данные различаются для треугольников и изолиновых доменов.
Tessellator фиксированной функции не просматривает другие выходные данные шейдера корпуса, такие как другие константы исправлений или какие-либо контрольные точки. Шейдер домена, который вызывается для каждой точки, которую создает tessellator фиксированной функции, будет видеть в качестве входных данных все контрольные точки вывода шейдера корпуса и все выходные данные исправлений; Шейдер оценивает исправление в своем расположении.
Определите константную функцию исправления. Константная функция исправления выполняется один раз для каждого исправления, чтобы вычислить любые данные, которые являются постоянными для всего исправления (в отличие от данных для каждой контрольной точки, которые вычисляются в шейдере корпуса).
#define MAX_POINTS 32 // Patch Constant Function HS_CONSTANT_DATA_OUTPUT SubDToBezierConstantsHS( InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip, uint PatchID : SV_PrimitiveID ) { HS_CONSTANT_DATA_OUTPUT Output; // Insert code to compute Output here return Output; }
Свойства функции patch constant включают:
- Один из входных данных указывает переменную, содержащую идентификатор исправления, и определяется системным значением SV_PrimitiveID (см. семантику в модели шейдера 4).
- Одним из входных параметров являются контрольные точки ввода, объявленные в VS_CONTROL_POINT_OUTPUT в этом примере. Функция patch может просматривать все контрольные точки ввода для каждого исправления. В этом примере на каждое исправление имеется 32 контрольные точки.
- Как минимум, функция должна вычислять коэффициенты тесселяции каждого патча для этапа тесселлатора, которые идентифицируются с помощью SV_TessFactor. Для четырехдоменного домена требуется четыре фактора тесселяции для ребер и два дополнительных фактора (определяемых SV_InsideTessFactor) для тесселяции внутренней части патча. Tessellator фиксированной функции не просматривает другие выходные данные шейдера корпуса (например, данные константы исправления или какие-либо контрольные точки).
- Выходные данные обычно определяются структурой и определяются HS_CONSTANT_DATA_OUTPUT в этом примере; Структура зависит от типа домена и будет отличаться для треугольников или изолиновых доменов.
С другой стороны, шейдер предметной области вызывается для каждой точки, которую создает тесселятор фиксированной функции, и должен просматривать выходные контрольные точки и выходные данные константы исправления (как из шейдера корпуса), чтобы оценить исправление в его расположении.
Определите шейдер корпуса. Шейдер корпуса определяет свойства исправления, включая функцию константы исправления. Шейдер оболочки вызывается один раз для каждой точки управления выходом.
[domain("quad")] [partitioning("integer")] [outputtopology("triangle_cw")] [outputcontrolpoints(16)] [patchconstantfunc("SubDToBezierConstantsHS")] BEZIER_CONTROL_POINT SubDToBezierHS( InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip, uint i : SV_OutputControlPointID, uint PatchID : SV_PrimitiveID ) { VS_CONTROL_POINT_OUTPUT Output; // Insert code to compute Output here. return Output; }
Шейдер корпуса использует следующие атрибуты:
- Атрибут домена .
- Атрибут секционирования .
- Атрибут outputtopology .
- Атрибут outputcontrolpoints .
- Атрибут patchconstantfunc . Шейдер корпуса вычисляет контрольные точки вывода. В этом примере имеется 16 выходных контрольных точек Безье.
Все контрольные точки ввода (определяемые VS_CONTROL_POINT_OUTPUT) видны каждому вызову шейдера корпуса. В этом примере имеется 32 контрольные точки ввода.
Шейдер оболочки вызывается один раз для каждой контрольной точки вывода (идентифицируемой с помощью SV_OutputControlPointID) для каждого исправления (определяемого SV_PrimitiveID). Цель этого конкретного шейдера — вычислить выходные данные i, которые были определены как контрольная точка BEZIER (в этом примере имеется 16 контрольных точек, определенных выходными точками управления).
Шейдер корпуса выполняет подпрограмму один раз для каждого исправления (функция константы исправления) для вычисления данных с константой исправления (факторы тесселяции как минимум). Отдельно шейдер корпуса выполняет функцию константы исправления (под названием SubDToBezierConstantsHS) для каждого исправления для вычисления данных о константах исправления, таких как факторы тесселяции для этапа тесселлатора.
Связанные темы