语义学

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

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

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

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

顶点着色器语义

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

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

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

像素着色器语义

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

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

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


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

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

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

仅 Direct3D 10 和更新支持语义。

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

System-Value 语义

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

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

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

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

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

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

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

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

System-Value 语义 描述 类型
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 硬件 上的用户剪辑平面。
SV_CullDistance[n] Cull 距离数据。 如果为顶点元素的 component(s)提供此标签,则每个值都假定为平面的 float32 有符号距离。 如果基元中的所有顶点的平面距离 < 0,将完全丢弃基元。 通过将一个或多个顶点元素的多个组件声明为SV_CullDistance,可以同时使用多个空平面。 组合的剪辑和剔除距离值最多是 D3D#_CLIP_OR_CULL_DISTANCE_COUNT 组件,大多数 D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT 寄存器。 可供读取或写入的所有着色器使用,但顶点着色器可以写入值,但不能将其用作输入。
SV_Coverage 可以在输入、输出或两个像素着色器上指定掩码。
对于像素着色器上的SV_Coverage,ps_4_1或更高版本支持 OUTPUT。
对于像素着色器的SV_Coverage,INPUT 需要ps_5_0或更高版本。
uint
SV_Depth 深度缓冲区数据。 可以通过像素着色器编写。
SV_DepthGreaterEqual 在像素着色器中,允许输出深度,只要它大于或等于光栅器确定的值。 启用调整深度,而无需禁用早期 Z。
SV_DepthLessEqual 在像素着色器中,允许输出深度,只要它小于或等于光栅器确定的值。 启用调整深度,而无需禁用早期 Z。
SV_DispatchThreadID 定义调度调用中的全局线程偏移量,每个组的维度。 作为计算着色器的输入提供。 (只读) uint3
SV_DomainLocation 定义正在评估的当前域点的外壳上的位置。 可用作域着色器的输入。 (只读) float2|3
SV_GroupID 定义 Dispatch 调用中的组偏移量,每个调度调用的维度。 作为计算着色器的输入提供。 (只读) uint3
SV_GroupIndex 为给定组中的给定线程提供平展索引。 作为计算着色器的输入提供。 (只读) uint
SV_GroupThreadID 定义组内每个维度的线程偏移量。 作为计算着色器的输入提供。 (只读) uint3
SV_GSInstanceID 定义几何着色器的实例。 可用作几何着色器的输入。 需要实例,因为在同一几何图形基元上最多可以调用 32 次几何着色器。 uint
SV_InnerCoverage 表示低估的保守光栅化信息(即是否保证像素to-be完全覆盖)。 可以读取或写入像素着色器。
SV_InsideTessFactor 定义修补图面中的分割量。 可在外壳着色器中用于写入,并在域着色器中可用于读取。 float|float[2]
SV_InstanceID 运行时自动生成的每个实例标识符(请参阅 使用 System-Generated 值(Direct3D 10))。 适用于所有着色器。
SV_IsFrontFace 指定三角形是否正面。 对于行和点,IsFrontFace 的值为 true。 例外情况是用三角形(线框模式)绘制的线条,该模式设置 IsFrontFace 的方式与以实心模式光栅化三角形的方式相同。 可以由几何着色器写入,并由像素着色器读取。 bool
SV_OutputControlPointID 定义通过调用外壳着色器的主要入口点来作的控制点 ID 的索引。 只能由外壳着色器读取。 uint
SV_Position 当为着色器输入声明SV_Position时,它可以指定以下两种内插模式之一:linearNoPerspective 或 linearNoPerspectiveCentroid,后者会导致在多重采样抗锯齿时提供质心贴靠 xyzw 值。 在着色器中使用时,SV_Position描述像素位置。 在所有着色器中可用,以获取具有 0.5 偏移量的像素中心。 float4
SV_PrimitiveID 运行时自动生成的每基元标识符(请参阅 使用 System-Generated 值(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 运行时自动生成的每顶点标识符(请参阅 使用 System-Generated 值(Direct3D 10))。 仅作为顶点着色器的输入提供。 uint
SV_ViewportArrayIndex 视区数组索引。 应用于几何着色器输出,并指示要用于当前写出基元的视区。可以由像素着色器读取。 在将基元传递给光栅器之前,将针对索引指定的视区进行转换和剪裁。 此语义仅适用于基元;如果基元有多个顶点,则使用前导顶点中的值。
如果 trueD3D11_FEATURE_DATA_D3D11_OPTIONS3::VPAndRTArrayIndexFromAnyShaderFeedingRasterizer,则SV_ViewportArrayIndex应用于为光栅器馈送的任何着色器。
uint
SV_ShadingRate 通过着色速率 定义由一个像素着色器调用为 可变着色速率第 2 层 或更高版本写入的像素数。 可以从像素着色器中读取。 可以从顶点或几何着色器编写。 uint

编写SV_Depth时的限制:

  • 当多重采样(在 D3D10_RASTERIZER_DESCTRUE)和写入深度值(使用像素着色器)时,深度测试中也会使用单个值:因此,多重采样时,以更高的分辨率呈现基元边缘的能力会丢失。
  • 使用动态流控制时,在编译时无法确定在某些路径中写入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 深度
SV_Position 位置
SV_Target 颜色

[!]请注意 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 硬件 上的用户剪辑平面。