语义

语义是附加到着色器输入或输出的字符串,用于传达有关参数预期用途的信息。 在着色器阶段之间传递的所有变量都需要语义。 此处显示了向着色器变量添加语义的语法(变量语法 (DirectX HLSL))。

通常,在管道阶段之间传递的数据完全通用,并且不被系统唯一解释;允许使用没有特殊含义的任意语义。 包含这些特殊语义的参数(在 Direct3D 10 及更高版本中)称为系统值语义

在 Direct3D 9 和 Direct3D 10 及更高版本中支持的语义

在 Direct3D 9 和 Direct3D 10 及更高版本中都支持以下类型的语义。

顶点着色器语义

附加到顶点着色器参数时,这些语义具有意义。 在 Direct3D 9 和 Direct3D 10 及更高版本中都支持这些语义。

输入 说明 类型
BINORMAL[n] Binormal float4
BLENDINDICES[n] 混合索引 uint
BLENDWEIGHT[n] 混合权重 FLOAT
COLOR[n] 漫射和反射颜色 float4
NORMAL[n] 法向矢量 float4
POSITION[n] 对象空间中的顶点位置。 float4
POSITIONT 变换的顶点位置。 float4
PSIZE[n] 点大小 FLOAT
TANGENT[n] 正切 float4
TEXCOORD[n] 纹理坐标 float4
输出 说明 类型
COLOR[n] 漫射或反射颜色 float4
顶点雾化 FLOAT
POSITION[n] 同质空间中的顶点位置。 通过将 (x,y,z) 除以 w 来计算屏幕空间中的位置。 每个顶点着色器都必须写出具有此语义的参数。 注意:此语义在 Direct3D 9 中可用。 对于 Direct3D 10 及更高版本,请改用 SV_Position。 float4
PSIZE 点大小 FLOAT
TESSFACTOR[n] 细化因素 FLOAT

n 是介于 0 和支持的资源数量之间的可选整数。 例如,POSITION0、TEXCOORD1 等。

像素着色器语义

附加到像素着色器输入参数时,这些语义具有意义。 在 Direct3D 9 和 Direct3D 10 及更高版本中都支持这些语义。

输入 说明 类型
COLOR[n] 漫射或反射颜色。 float4
TEXCOORD[n] 纹理坐标 float4
VFACE 指示后置基元的浮点标量。 负值向后移动,而正值面对相机。

注意:
此语义在 Direct3D 9 着色器模型 3.0 中可用。 对于 Direct3D 10 及更高版本,请改用 SV_IsFrontFace


FLOAT
VPOS 屏幕空间中的像素位置 (x,y)。 要将 Direct3D 9 着色器(使用此语义)转换为 Direct3D 10 及更高版本的着色器,请参阅 Direct3D 9 VPOS 和 Direct3D 10 SV_Position float2
输出 说明 类型
COLOR[n] 输出颜色 float4
DEPTH[n] 输出深度 FLOAT

n 是介于 0 和支持的资源数量之间的可选整数。 例如,PSIZE0、COLOR1 等。

COLOR 语义仅在着色器兼容模式下有效(即,使用 D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY 创建着色器时)。

仅在 Direct3D 10 和更高版本中支持语义。

最近为 Direct3D 10 引入了以下类型的语义,不适用于 Direct3D 9。

系统值语义

系统值语义在 Direct3D 10 中属于新功能。 所有系统值都以 SV_ 前缀开头,一个常见示例是 SV_POSITION,它由光栅化阶段解释。 系统值在管道的其他部分中有效。 例如,可以将 SV_Position 指定为顶点着色器和输出的输入。 像素着色器只能使用 SV_Depth 和 SV_Target 系统值语义写入参数。

其他系统值(SV_VertexID、SV_InstanceID、SV_IsFrontFace)只能输入到管道中可以解释特定值的第一个活动着色器;之后,着色器函数必须将值传递到后续阶段。

SV_PrimitiveID 是此规则(即仅输入到管道中的第一个可以解释特定值的活动着色器)的例外;硬件可以提供与外壳着色器阶段、域着色器阶段以及在此后几何着色器阶段或像素着色器阶段中第一个启用的阶段的输入相同的 ID 值。

如果启用了网格化,则存在外壳着色器阶段和域着色器阶段。 对于给定的修补程序,相同的 PrimitiveID 适用于修补程序的外壳着色器调用,以及所有细化的域着色器调用。 相同 PrimitiveID 还会传播到下一个活动阶段:几何着色器阶段或像素着色器阶段(如果启用)。

如果几何着色器输入 SV_PrimitiveID,并且因为它可以为每个调用输出零个、一个或多个基元输出,因此着色器必须在后续像素着色器输入 SV_PrimtiveID 时对每个输出基元的 SV_PrimitiveID 值进行编程。

另一个示例是顶点着色器阶段无法解释 SV_PrimitiveID,因为顶点可以是多个基元的成员。

这些语义已添加到 Direct3D 10;它们在 Direct3D 9 中不可用。

光栅化阶段的系统值语义。

系统值语义 说明 类型
SV_ClipDistance[n] 剪辑距离数据。 SV_ClipDistance 值各自假定为平面的 float32 有符号距离。 基元设置仅对内插平面距离为 >= 0 的像素调用光栅化。 通过将一个或多个顶点元素的多个组件声明为 SV_ClipDistance,可以同时实现多个剪辑平面。 组合剪辑和剔除距离值是最多 D3D#_CLIP_OR_CULL_DISTANCE_COUNT 个组件,位于最多 D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT 个寄存器中。 可供读取或写入的所有着色器使用,但顶点着色器可以写入值,不能将其用作输入。
剪辑平面属性的工作方式类似于 SV_ClipDistance,但适用于功能级别 9_x 和更高版本的所有硬件。 有关详细信息,请参阅功能级别 9 硬件上的用户剪辑平面
FLOAT
SV_CullDistance[n] 剔除距离数据。 如果为顶点元素的组件提供此标签,则每个值都假定为平面的 float32 有符号距离。 如果基元中的所有顶点的平面距离都 < 0,则基元将被完全丢弃。 通过将一个或多个顶点元素的多个组件声明为 SV_CullDistance,可以同时使用多个剔除平面。 组合剪辑和剔除距离值是最多 D3D#_CLIP_OR_CULL_DISTANCE_COUNT 个组件,位于最多 D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT 个寄存器中。 可供读取或写入的所有着色器使用,但顶点着色器可以写入值,不能将其用作输入。
FLOAT
SV_Coverage 可以在输入、输出或两种像素着色器上指定掩码。
对于像素着色器上的 SV_Coverage,ps_4_1 或更高版本支持 OUTPUT。
对于像素着色器上的 SV_Coverage,INPUT 需要 ps_5_0 或更高版本。
uint
SV_Depth 深度缓冲区数据。 可由像素着色器写入。 FLOAT
SV_DepthGreaterEqual 在像素着色器中,只要大于或等于光栅器确定的值,就允许输出深度。 启用调整深度,而不禁用早期 Z。 FLOAT
SV_DepthLessEqual 在像素着色器中,只要小于或等于光栅器确定的值,就允许输出深度。 启用调整深度,而不禁用早期 Z。 FLOAT
SV_DispatchThreadID 根据组的维度定义调度调用中的全局线程偏移量。 可用作计算着色器的输入。 (只读) uint3
SV_DomainLocation 定义正在评估的当前域点的外壳上的位置。 可用作域着色器的输入。 (只读) float2|3
SV_GroupID 根据调度调用的维度定义调度调用中的组偏移量。 可用作计算着色器的输入。 (只读) uint3
SV_GroupIndex 为给定组中的给定线程提供平展的索引。 可用作计算着色器的输入。 (只读) uint
SV_GroupThreadID 根据组的维度定义组中的线程偏移量。 可用作计算着色器的输入。 (只读) uint3
SV_GSInstanceID 定义几何着色器的实例。 可用作几何着色器的输入。 需要实例,因为在同一几何图形基元上最多可以调用 32 次几何着色器。 uint
SV_InnerCoverage 表示低估的保守光栅化信息(即是否为保证完全覆盖像素)。 可由像素着色器读取或写入。
SV_InsideTessFactor 定义修补面中的分割量。 在外壳着色器中可用于写入,在域着色器中可用于读取。 float|float[2]
SV_InstanceID 由运行时自动生成的每个实例的标识符(请参阅使用系统生成的值 (Direct3D 10))。 可用于所有着色器。
SV_IsFrontFace 指定三角形是否朝前。 对于行和点,IsFrontFace 的值为 true。 例外情况是用三角形(线框模式)绘制的线条,它设置 IsFrontFace 的方式与以实心模式光栅化三角形的方式相同。 可由几何着色器写入,并由像素着色器读取。 布尔
SV_OutputControlPointID 定义通过调用外壳着色器的主要入口点来操作的控制点 ID 的索引。 仅可由外壳着色器读取。 uint
SV_Position 为着色器输入声明 SV_Position 时,它可指定以下两种内插模式之一:linearNoPerspective 或 linearNoPerspectiveCentroid,后者会导致在多重采样抗锯齿时提供质心贴靠 xyzw 值。 在着色器中使用时,SV_Position 描述像素位置。 在所有着色器中可用于以 0.5 的偏移量获取像素中心。 float4
SV_PrimitiveID 由运行时自动生成的每个基元的标识符(请参阅使用系统生成的值 (Direct3D 10))。 可由几何图形或像素着色器写入,并由几何、像素、外壳或域着色器读取。 uint
SV_RenderTargetArrayIndex 渲染目标数组索引。 应用于几何着色器输出,指示像素着色器将基元绘制到的呈现器目标数组切片。 仅当呈现器目标为数组资源时,SV_RenderTargetArrayIndex 才有效。 此语义仅适用于基元;如果基元有多个顶点,则使用来自前导顶点的值。 此值还指示深度/模具视图的哪个数组切片用于读/写目的。
可以从几何着色器写入,并由像素着色器读取。
如果 D3D11_FEATURE_DATA_D3D11_OPTIONS3::VPAndRTArrayIndexFromAnyShaderFeedingRasterizertrue,则 SV_RenderTargetArrayIndex 应用于馈送光栅器的任何着色器。
uint
SV_SampleIndex 示例频率索引数据。 仅可由像素着色器读取或写入。 uint
SV_StencilRef 表示当前像素着色器模具参考值。 仅可由像素着色器写入。 uint
SV_Target[n],其中 0 <= n <= 7 将存储在呈现器目标中的输出值。 索引指示要写入到 8 个可能绑定的呈现器目标中的哪一个。 该值适用于所有着色器。 float[2|3|4]
SV_TessFactor 定义补丁每个边缘的分割量。 可用于在外壳着色器中写入和在域着色器中读取。 float[2|3|4]
SV_VertexID 由运行时自动生成的每个顶点的标识符(请参阅使用系统生成的值 (Direct3D 10))。 仅可用作顶点着色器的输入。 uint
SV_ViewportArrayIndex 视区数组索引。 应用于几何着色器输出,指示要用于当前写出基元的视区。可以由像素着色器读取。 在将基元传递给光栅器之前,将针对索引指定的视区进行变换和剪辑。 此语义仅适用于基元;如果基元有多个顶点,则使用来自前导顶点的值。
如果 D3D11_FEATURE_DATA_D3D11_OPTIONS3::VPAndRTArrayIndexFromAnyShaderFeedingRasterizertrue,则 SV_ViewportArrayIndex 应用于馈送光栅器的任何着色器。
uint
SV_ShadingRate 通过着色速率定义由一个像素着色器调用为可变着色速率第 2 层或更高版本设备写入的像素数。 可以从像素着色器读取。 可以从顶点或几何着色器写入。 uint

写入 SV_Depth 时的限制:

  • 当多重采样(D3D10_RASTERIZER_DESC 中的 MultisampleEnable 为 TRUE)和写入深度值(使用像素着色器)时,在深度测试中也会使用写出的单个值;因此在多重采样时,以更高分辨率呈现基元边缘的能力丢失。
  • 使用动态流控制时,在编译时无法确定在某些路径中写入 SV_Depth 的着色器是否保证在每次执行时都写入 SV_Depth。 声明后无法写入 SV_Depth 会导致未定义的行为(这可能包括丢弃像素)。
  • 任何 float32 值(包括 +/-INF 和 NaN)都可以写入 SV_Depth。
  • 执行双源颜色混合时,写入 SV_Depth 功能仍然有效。

从 Direct3D 9 迁移到 Direct3D 10 及更高版本

在将代码从 Direct3D 9 迁移到 Direct3D 10 及更高版本时,应考虑以下问题:

映射到 Direct3D 9 语义

一些 Direct3D 10 及更高版本的语义直接映射到 Direct3D 9 语义。

Direct3D 10 语义 Direct3D 9 等效语义
SV_Depth DEPTH
SV_Position POSITION
SV_Target COLOR

[!] Direct3D 9 开发人员注意事项:对于 Direct3D 9 目标,着色器语义必须映射到有效的 Direct3D 9 语义。 为了向后兼容,FXC 会将 POSITION0(及其变体名称)视为 SV_Position。 FXC 将 COLOR 视为 SV_TARGET。 DXC 和较新的编译器将 POSITION[n] 和 COLOR 视为用户定义的语义。

Direct3D 9 VPOS 和 Direct3D 10 SV_Position

D3D10 语义 SV_Position 提供与 Direct3D 9 着色器模型 3 VPOS 语义类似的功能。 例如,在 Direct3D 9 中,下面的语法用于使用屏幕空间坐标的像素着色器:

float4 psMainD3D9( float4 screenSpace : VPOS ) : COLOR
{
    // code here 
}

为着色器模型 3 支持添加了 VPOS 以指定屏幕空间坐标,因为 POSITION 语义适用于对象空间坐标。

在 Direct3D 10 及更高版本中,SV_Position 语义(在像素着色器的上下文中使用时)指定屏幕空间坐标(偏移量为 0.5)。 因此,Direct3D 9 着色器大致等效(未考虑 0.5 偏移量),如下所示:

float4 psMainD3D10( float4 screenSpace : SV_Position ) : COLOR
{
    // code here
}

从 Direct3D 9 迁移到 Direct3D 10 及更高版本时,需要在转换着色器时注意这一点。

HLSL 中的用户剪辑平面

从 Windows 8 开始,可以使用 HLSL 函数声明中的剪辑平面函数属性(而非 SV_ClipDistance)使着色器能够处理功能级别 9_x 以及功能级别 10 和更高版本。 有关详细信息,请参阅功能级别 9 硬件上的用户剪辑平面