状态对象

使用着色器模型 6.3 及更高版本时,除了使用 Direct3D 12 API 外,应用程序还可以方便地灵活地在 HLSL 着色器代码中直接定义 DXR 状态对象。

在 HLSL 中,使用以下语法声明状态对象:

Type Name = 
{ 
    Field1,
    Field2,
    ...
};
说明
类型
标识子对象的类型。 必须是受支持的 HLSL 子对象类型之一。
名字
唯一标识变量名称的 ASCII 字符串。
Field[1, 2, ...]
子对象的字段。 下面介绍了每种类型的子对象的特定字段。

子对象类型列表:

StateObjectConfig

StateObjectConfig 子对象类型对应于 D3D12_STATE_OBJECT_CONFIG 结构。

它有一个字段,一个按位标志,它是一个或两个

  • STATE_OBJECT_FLAGS_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITONS
  • STATE_OBJECT_FLAGS_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS

或,两者均不为零。

示例:

StateObjectConfig MyStateObjectConfig = 
{ 
    STATE_OBJECT_FLAGS_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITONS
};

GlobalRootSignature

GlobalRootSignature 对应于 D3D12_GLOBAL_ROOT_SIGNATURE 结构。

字段由一些描述根签名部分的字符串组成。 有关此方面的参考,请参阅 在 HLSL 中指定根签名

示例:

GlobalRootSignature MyGlobalRootSignature =
{
    "DescriptorTable(UAV(u0)),"                     // Output texture
    "SRV(t0),"                                      // Acceleration structure
    "CBV(b0),"                                      // Scene constants
    "DescriptorTable(SRV(t1, numDescriptors = 2))"  // Static index and vertex buffers.
};

LocalRootSignature

LocalRootSignature 对应于 D3D12_LOCAL_ROOT_SIGNATURE 结构。

与全局根签名子对象一样,字段由描述根签名部分的一些字符串组成。 有关此方面的参考,请参阅 在 HLSL 中指定根签名

示例:

LocalRootSignature MyLocalRootSignature = 
{
    "RootConstants(num32BitConstants = 4, b1)"  // Cube constants 
};

SubobjectToExportsAssocation

默认情况下,仅在与导出相同的库中声明的子对象能够应用于该导出。 但是,应用程序能够重写该对象,并获取与哪个导出一起的子对象的具体信息。 在 HLSL 中,此“显式关联”是使用 SubobjectToExportsAssocation 完成的。

SubobjectToExportsAssocation 对应于 D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION 结构。

此子对象是使用 语法声明的

SubobjectToExportsAssocation Name = 
{ 
    SubobjectName,
    Exports
};
说明
名字
唯一标识变量名称的 ASCII 字符串。
SubobjectName
标识导出的子对象的字符串。
出口
包含以分号分隔的导出列表的字符串。

示例:

SubobjectToExportsAssociation MyLocalRootSignatureAssociation =
{
    "MyLocalRootSignature",    // Subobject name
    "MyHitGroup;MyMissShader"  // Exports association 
};

请注意,这两个字段都使用 导出 的名称。 如果应用程序选择执行导出重命名,导出的名称可能与 HLSL 中的原始名称不同。

RaytracingShaderConfig

RaytracingShaderConfig 对应于 D3D12_RAYTRACING_SHADER_CONFIG 结构。

此子对象是使用 语法声明的

RaytracingShaderConfig Name = 
{ 
    MaxPayloadSize,
    MaxAttributeSize
};
说明
名字
唯一标识变量名称的 ASCII 字符串。
MaxPayloadSize
标量最大存储的数值 (在关联光线跟踪着色器) 光线有效负载中计算为 4 个字节。
MaxAttributeSize
最大标量数的数值 (计为 4 个字节,每个) 可用于关联光线追踪着色器中的属性。 该值不能超过 D3D12_RAYTRACING_MAX_ATTRIBUTE_SIZE_IN_BYTES

示例:

RaytracingShaderConfig MyShaderConfig =
{
    16,  // Max payload size
    8    // Max attribute size
};

RaytracingPipelineConfig

RaytracingPipelineConfig 对应于 D3D12_RAYTRACING_PIPELINE_CONFIG 结构。

此子对象是使用 语法声明的

RaytracingPipelineConfig Name = 
{ 
    MaxTraceRecursionDepth
};
说明
名字
唯一标识变量名称的 ASCII 字符串。
MaxTraceRecursionDepth
用于光线跟踪管道中光线递归的数值限制。 它是介于 0 和 31(含 0 和 31)之间的数字。

示例:

RaytracingPipelineConfig MyPipelineConfig =
{
    1  // Max trace recursion depth
};

由于光线追踪递归会产生性能成本,因此应用程序应使用所需结果所需的最低递归深度。

如果着色器调用尚未达到最大递归深度,则可以调用 TraceRay 任意次数。 但是,如果它们达到或超过最大递归深度,则调用 TraceRay 会将设备置于删除状态。 因此,如果光线跟踪着色器已达到或超过最大递归深度,应注意停止调用 TraceRay。

TriangleHitGroup

TriangleHitGroup 对应于类型字段设置为 D3D12_HIT_GROUP_TYPE_TRIANGLES 的D3D12_HIT_GROUP_DESC结构。

此子对象是使用 语法声明的

TriangleHitGroup Name = 
{ 
    AnyHitShader,
    ClosestHitShader
};
说明
名字
唯一标识变量名称的 ASCII 字符串。
AnyHitShader
命中组的 anyhit 着色器的字符串名称,或空字符串。
ClosestHitShader
命中组最近的命中着色器的字符串名称,或空字符串。

示例:

TriangleHitGroup MyHitGroup =
{
    "",                    // AnyHit
    "MyClosestHitShader",  // ClosestHit
};

请注意,这两个字段都使用 导出 的名称。 如果应用程序选择执行导出重命名,导出的名称可能与 HLSL 中的原始名称不同。

ProceduralPrimitiveHitGroup

ProceduralPrimitiveHitGroup 对应于 type 字段设置为D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE 的D3D12_HIT_GROUP_DESC结构。

此子对象是使用 语法声明的

ProceduralPrimitiveHitGroup Name = 
{ 
    AnyHitShader,
    ClosestHitShader,
    IntersectionShader
};
说明
名字
唯一标识变量名称的 ASCII 字符串。
AnyHitShader
命中组的 anyhit 着色器的字符串名称,或空字符串。
ClosestHitShader
命中组最近的命中着色器的字符串名称,或空字符串。
IntersectionShader
命中组的交集着色器的字符串名称或空字符串。

示例:

ProceduralPrimitiveHitGroup MyProceduralHitGroup
{
    "MyAnyHit",       // AnyHit
    "MyClosestHit",   // ClosestHit
    "MyIntersection"  // Intersection
};

请注意,这三个字段使用 导出 的名称。 如果应用程序选择执行导出重命名,则导出的名称可能与 HLSL 中的原始名称不同。

备注

子对象具有“关联”或“哪个子对象与哪个导出一起”的概念。

通过着色器代码指定子对象时,“哪个子对象用于哪个导出”的选择遵循 DXR 规范中概述的规则。 具体而言,假设应用程序具有某种导出。 如果应用程序通过着色器代码将导出与根签名 A 关联,通过应用程序代码将根签名 B 关联,则 B 是被使用的签名。 “使用 B”而不是“生成错误”的设计使应用程序能够方便地使用应用程序代码替代 DXIL 关联,而不是被迫重新编译着色器来解决不匹配的问题。

DirectX 开发人员博客文章“D3D12 中的新增功能 - DirectX 光线跟踪 (DXR) 现在支持库子对象”

DirectX 光线跟踪 (DXR) 功能规范

示例:D3D12RaytracingLibrarySubobjects