语义是附加到着色器输入或输出的字符串,用于传达有关参数的预期用途的信息。 在着色器阶段之间传递的所有变量都需要语义。 此处显示了向着色器变量添加语义的语法 (
变量语法 (DirectX HLSL)
) 。
一般情况下,在管道阶段之间传递的数据是完全通用的,系统不会唯一解释:允许使用没有特殊含义的任意语义。 Direct3D 10 及更高版本中 (的参数) 这些特殊语义称为
系统值语义
。
Direct3D 9 和 Direct3D 10 及更高版本中支持的语义
Direct3D 9 和 Direct3D 10 及更高版本中都支持以下类型的语义。
顶点着色器语义
像素着色器语义
顶点着色器语义
这些语义在附加到顶点着色器参数时具有意义。 Direct3D 9 和 Direct3D 10 及更高版本中都支持这些语义。
屏幕空间中的像素位置 (x,y) 。 若要将此语义) 的 Direct3D 9 着色器 (转换为 Direct3D 10 及更高版本的着色器,请参阅
Direct3D 9 VPOS 和 Direct3D 10 SV_Position
)
float2
n
是介于 0 和支持的资源数之间的可选整数。 例如 PSIZE0、COLOR1 等。
COLOR 语义仅在着色器兼容模式下有效, (即使用 D3D10_SHADER_ENABLE_BACKWARDS_COMPATIBILITY) 创建着色器时。
仅 Direct3D 10 和更新版本支持的语义。
以下类型的语义是针对 Direct3D 10 新引入的,不适用于 Direct3D 9。
系统值语义
System-Value语义
系统值语义是 Direct3D 10 的新增功能。 所有系统值都以SV_前缀开头,一个常见示例是SV_POSITION,它由光栅器阶段解释。 系统值在管道的其他部分有效。 例如,可以将SV_Position指定为顶点着色器的输入和输出。 像素着色器只能使用SV_Depth和SV_Target系统值语义写入参数。
(SV_VertexID、SV_InstanceID、SV_IsFrontFace) 的其他系统值只能输入到管道中可以解释特定值的第一个活动着色器中;之后,着色器函数必须将值传递给后续阶段。
SV_PrimitiveID是此规则的例外,即仅输入管道中可以解释特定值的第一个活动着色器;硬件可以提供与外壳着色器阶段、域着色器阶段以及之后第一个启用的阶段的输入相同的 ID 值:geometry-shader 阶段或像素着色器阶段。
如果启用了分割,则存在外壳着色器阶段和域着色器阶段。 对于给定的修补程序,相同的 PrimitiveID 适用于修补程序的外壳着色器调用以及所有细化域着色器调用。 相同的 PrimitiveID 也会传播到下一个活动阶段;geometry-shader 阶段或像素着色器阶段(如果已启用)。
如果几何着色器输入SV_PrimitiveID并且由于每次调用可以输出零个或多个基元,如果后续像素着色器输入SV_PrimtiveID,则着色器必须为每个输出基元编写自己选择的SV_PrimitiveID值。
再举一个例子,顶点着色器阶段无法解释SV_PrimitiveID,因为顶点可以是多个基元的成员。
这些语义已添加到 Direct3D 10;它们在 Direct3D 9 中不可用。
光栅器阶段的系统值语义。
System-Value语义
SV_ClipDistance[n]
剪辑距离数据。 SV_ClipDistance值都假定为浮点 32 有符号距离到平面。 基元设置仅对内插平面距离 () >= 0 的像素调用光栅化。 通过将一个或多个顶点元素的多个组件 () 声明为SV_ClipDistance,可以同时实现多个剪裁平面。 组合的剪辑和剔除距离值在最多 D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT 寄存器中最多是 D3D#_CLIP_OR_CULL_DISTANCE_COUNT分量。 适用于所有要读取或写入的着色器,但顶点着色器除外,它可以写入值,但不能将其作为输入。
剪辑平面
属性的工作方式类似于SV_ClipDistance但适用于所有硬件
功能级别
9_x及更高。 有关详细信息,请参阅
功能级别 9 硬件上的用户剪辑平面
。
FLOAT
SV_CullDistance[n]
剔除距离数据。 如果为组件 (顶点元素 () ) 此标签,则假定这些值与平面之间的 float32 有符号距离。 如果基元中所有顶点的平面距离 (s) ,则基元 < 将被完全丢弃。 通过将一个或多个顶点元素的多个组件 () 声明为SV_CullDistance,可以同时使用多个空平面。 组合的剪辑和剔除距离值在最多 D3D#_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT 寄存器中最多是 D3D#_CLIP_OR_CULL_DISTANCE_COUNT分量。 适用于所有要读取或写入的着色器,但顶点着色器除外,它可以写入值,但不能将其作为输入。
FLOAT
SV_Coverage
可以在输入和/或输出上指定的掩码。
对于像素着色器上的SV_Coverage,输出在 ps_4_1 或更高版本上受支持。
对于像素着色器上的SV_Coverage,INPUT 需要ps_5_0或更高版本。
SV_Depth
深度缓冲区数据。 可由像素着色器写入。
FLOAT
SV_DepthGreaterEqual
在像素着色器中,只要深度大于或等于光栅器确定的值,就可以输出深度。 在不禁用早期 Z 的情况下启用调整深度。
FLOAT
SV_DepthLessEqual
在像素着色器中,允许输出深度,只要深度小于或等于光栅器确定的值。 在不禁用早期 Z 的情况下启用调整深度。
FLOAT
SV_DispatchThreadID
定义 Dispatch 调用中的全局线程偏移量(按组的维度)。 可用作计算着色器的输入。 (只读)
uint3
SV_DomainLocation
定义正在评估的当前域点的外壳上的位置。 可用作域着色器的输入。 (只读)
float2|3
SV_GroupID
根据调度调用的维度定义调度调用中的组偏移量。 可用作计算着色器的输入。 (只读)
uint3
SV_GroupIndex
为给定组中的给定线程提供平展索引。 可用作计算着色器的输入。 (只读)
SV_GroupThreadID
定义组内每个组维度的线程偏移量。 可用作计算着色器的输入。 (只读)
uint3
SV_GSInstanceID
定义几何着色器的实例。 可用作几何着色器的输入。 需要 实例,因为几何着色器最多可在同一几何基元上调用 32 次。
SV_InnerCoverage
表示低估的保守光栅化信息 (即像素是否保证) 完全覆盖。 可由像素着色器读取或写入。
SV_InsideTessFactor
定义修补图面中的分割量。 在外壳着色器中可用于写入,在域着色器中可用于读取。
float|float[2]
SV_InstanceID
运行时自动生成的每个实例标识符 (请参阅
使用 System-Generated 值 (Direct3D 10)
) 。 适用于所有着色器。
SV_IsFrontFace
指定三角形是否为正面。 对于线条和点,IsFrontFace 的值为 true。 例外是线框模式) (三角形中绘制的线条,这与在实心模式下光栅化三角形的方式相同。 可由几何着色器写入,并由像素着色器读取。
SV_OutputControlPointID
定义由调用外壳着色器main入口点操作的控制点 ID 的索引。 只能由外壳着色器读取。
SV_Position
声明SV_Position以输入到着色器时,它可以指定两种内插模式之一:linearNoPerspective 或 linearNoPerspectiveCentroid,后者会导致在多重采样抗锯齿时提供质心贴靠的 xyzw 值。 在着色器中使用时,SV_Position描述像素位置。 可用于所有着色器,以获取偏移量为 0.5 的像素中心。
float4
SV_PrimitiveID
运行时自动生成的每个基元标识符 (请参阅
使用 System-Generated 值 (Direct3D 10) )
。 可由几何图形或像素着色器写入,并由几何图形、像素、外壳或域着色器读取。
SV_RenderTargetArrayIndex
Render-target 数组索引。 应用于几何着色器输出,并指示像素着色器将绘制基元的呈现目标数组切片。 仅当呈现器目标是数组资源时,SV_RenderTargetArrayIndex才有效。 此语义仅适用于基元;如果基元具有多个顶点,则使用前导顶点中的值。 此值还指示深度/模具视图的哪个数组切片用于读取/写入目的。
可以从几何着色器写入,并由像素着色器读取。
如果
D3D11_FEATURE_DATA_D3D11_OPTIONS3::VPAndRTArrayIndexFromAnyShaderFeedingRasterizer
为
true
,则SV_RenderTargetArrayIndex应用于为光栅器馈送的任何着色器。
SV_SampleIndex
采样频率索引数据。 只能由像素着色器读取或写入。
SV_StencilRef
表示当前像素着色器模具引用值。 只能由像素着色器写入。
SV_Target[n],其中 0 <= n <= 7
将存储在呈现器目标的输出值。 索引指示要写入的 8 个可能绑定的呈现目标中的哪一个。 该值适用于所有着色器。
float[2|3|4]
SV_TessFactor
定义补丁的每个边缘上的细化量。 可用于在外壳着色器中写入和在域着色器中读取。
float[2|3|4]
SV_VertexID
由运行时自动生成的每个顶点标识符 (请参阅
使用 System-Generated 值 (Direct3D 10)
) 。 仅可用作顶点着色器的输入。
SV_ViewportArrayIndex
视区数组索引。 应用于几何着色器输出,并指示要用于当前正在写出的基元的视区。可由像素着色器读取。 在将基元传递给光栅器之前,将针对索引指定的视区对其进行转换和剪裁。 此语义仅适用于基元;如果基元具有多个顶点,则使用前导顶点的值。
如果
D3D11_FEATURE_DATA_D3D11_OPTIONS3::VPAndRTArrayIndexFromAnyShaderFeedingRasterizer
为
true
,则SV_ViewportArrayIndex应用于为光栅器馈送的任何着色器。
SV_ShadingRate
通过着色速率
值
定义由一个像素着色器调用为
可变着色速率层 2
或更高层设备写入的像素数。 可以从像素着色器读取。 可以从顶点或几何着色器写入。
编写SV_Depth时的限制:
当多重采样 (MultisampleEnable 在
D3D10_RASTERIZER_DESC)
中为
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 等效语义
[!]Direct3D 9 开发人员注意:对于 Direct3D 9 目标,着色器语义必须映射到有效的 Direct3D 9 语义。 为了向后兼容 POSITION0 (及其变体名称) 被视为SV_Position,COLOR 被视为SV_TARGET。
映射到 Direct3D 9 语义
Direct3D 9 VPOS 和 Direct3D 10 SV_Position
HLSL 中的用户剪辑平面
Direct3D 9 VPOS 和 Direct3D 10 SV_Position
D3D10 语义SV_Position提供与 Direct3D 9 着色器模型 3 VPOS 语义类似的功能。 例如,在 Direct3D 9 中,以下语法用于使用屏幕空间坐标的像素着色器:
float4 psMainD3D9( float4 screenSpace : VPOS ) : COLOR
// code here
添加了 VPOS 以支持着色器模型 3,以指定屏幕空间坐标,因为 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 硬件上的用户剪辑平面。
(DirectX HLSL) 变量