Коротко и по делу — что обычно приходит в фрагментный (pixel) шейдер и в каких вариантах это писать в HLSL.
1) Откуда приходят аргументы
- Всё, что приходит в PS — это либо значения, переданные из вершинного шейдера (VS -> PS), либо системные значения/ресурсы (текстуры, константные буферы и т.п.).
- Связывание происходит через семантики (semantics): TEXCOORD0, COLOR0, SV_POSITION и т.д. Имя параметра может быть любым, важна семантика и тип.
2) Часто используемые семантики (входы PS)
- TEXCOORDn — любые интерполируемые данные (uv, normal в преобразованном виде, т.п.).
- COLORn — цвет, обычно как float4.
- SV_Position — позиция в экране (post-projection).
- SV_IsFrontFace — бул, видимость грани (для двусторонней отрисовки).
- SV_PrimitiveID, SV_SampleIndex, SV_RenderTargetArrayIndex — для специальных случаев.
- sample/centroid/nointerpolation + noperspective — уточняют интерполяцию (см. ниже).
3) Часто используемые ресурсы (непосредственно доступные в PS)
- Texture2D, Texture2DArray, TextureCube и т.п.
- SamplerState / SamplerComparisonState.
- cbuffer (константные буферы).
Обычно их объявляют как глобальные переменные или как параметры функции шейдера.
4) Что возвращает PS
- Обычно float4 : SV_Target — цвет пикселя.
- Можно возвращать struct с несколькими таргетами (SV_Target0, SV_Target1, …) или вместе с глубиной (SV_Depth).
5) Форматы функций (примеры)
- Через struct (обычно предпочтительный и читаемый способ):
struct PSInput {
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 norm : TEXCOORD1;
float4 col : COLOR0;
};
float4 PSMain(PSInput IN) : SV_Target {
// использовать IN.uv, IN.norm и т.д.
}
- Через отдельные параметры:
float4 PSMain(float2 uv : TEXCOORD0, float4 col : COLOR0) : SV_Target {
// ...
}
- Пример с ресурсами:
Texture2D tex0 : register(t0);
SamplerState samp : register(s0);
float4 PSMain(PSInput IN) : SV_Target {
float4 texcol = tex0.Sample(samp, IN.uv);
return texcol * IN.col;
}
6) Интерполяция / модификаторы
- nointerpolation — без интерполяции (например для flat shading).
- centroid — предотвращает артефакты при мультисэмплинге, если значение вычислено на краю.
- sample — передаёт значение per-sample (для мультисэмплинга).
- noperspective — линейная интерполяция в экране (без коррекции перспективы).
Пример: float3 normal : NORMAL; или nointerpolation float flatVal : TEXCOORD0;
7) Частые ошибки/подводные камни
- Семантика должна совпадать между VS и PS (или хотя бы семантика/регистры должны позволять интерполяцию).
- SV_POSITION в VS должен быть float4; если он есть в VS, то в PS он тоже может быть (чтобы знать экранную позицию пикселя).
- Типы должны быть совместимы (например, VS выдаёт float3 как TEXCOORD0, PS не должен ожидать float4 с той же семантикой).
- Если используете SV_Position в PS — это экранная позиция (в пикселях) и обычно float4, w не нормализован.
8) Примеры "рабочих вариантов", которые вы, возможно, видели
- Вариант 1: PS принимает struct с SV_POSITION и UV — работает.
- Вариант 2: PS принимает только float2 uv : TEXCOORD0 — тоже работает.
Оба корректны — это просто разные формы объявления входа.
Если нужно, могу разобрать конкретный код, который у вас не работает: пришлите сигнатуры VS и PS и какие семантики вы используете — покажу, где ошибка и как привести всё в соответствие.