config | 此光线追踪网格实例数组使用的公共参数。 |
instanceData | 光线追踪网格实例使用的一组实例数据。 |
instanceCount | 要添加到加速结构中的实例数量。当此参数为 -1(默认值)时,Unity 会从 startInstance 开始,将 instanceData 数组中的所有实例添加到加速结构中。 |
startInstance | 要添加到加速结构中的 instanceData 中的第一个实例。 |
id | 可选的实例 ID 值,您可以在 HLSL 中使用 InstanceID() 函数访问它。 |
int 表示一个句柄的值,您可以使用它执行后续操作(例如 RemoveInstance、UpdateInstancePropertyBlock)。
将一组光线追踪网格实例添加到 RayTracingAccelerationStructure 中。
传递的 instanceData 可以是 Matrix4x4 数组(每个实例的对象到世界变换)或自定义数据结构。当 instanceData 为自定义数据结构时,该结构可以包含以下成员
这些成员可以在结构中的任何位置出现,但它们必须具有上述名称和类型。AddInstances 会忽略您在结构中包含的用于自身用途的任何其他成员。以下自定义结构的示例定义了必需的 objectToWorld 成员、可选的 renderingLayerMask 成员以及自定义 weight 成员(AddInstances 函数会忽略此成员)。
struct MyInstanceData { public Matrix4x4 objectToWorld; // We must specify object-to-world transformation for each instance public uint renderingLayerMask; // Optional per-instance rendering layer mask. public float weight; // Additional per-instance data unrelated to rendering. };
为了获得最佳的 CPU 性能,MyInstanceData 应该只包含 objectToWorld 成员,否则 Unity 必须对数据进行解交织。
当 AddInstances 处于使用状态时,Unity 会启用 INSTANCING_ON
着色器关键字。要声明 HLSL 中的着色器关键字,请在 RayTracingShader.SetShaderPass 或 CommandBuffer.SetRayTracingShaderPass 中指定的着色器通道中添加 #pragma multi_compile _ INSTANCING_ON
。要访问相对于此光线追踪实例数组的每个实例数据,请在 HLSL 中使用 InstanceIndex() - unity_BaseInstanceID
作为实例索引。例如,如果 MyInstanceData 结构中存在 prevObjectToWorld 成员,Unity 会将值复制到 unity_PrevObjectToWorldArray
缓冲区,您可以在 HLSL 中将其定义为 StructuredBuffer<float4x4> unity_PrevObjectToWorldArray;
然后,您可以使用 InstanceIndex() - unity_BaseInstanceID
差值索引缓冲区。以下 HLSL 代码段演示了如何计算世界空间速度矢量,该矢量输出在光线负载中
#pragma multi_compile _ INSTANCING_ON
struct AttributeData { float2 barycentrics; };
struct RayPayload { float3 velocity; };
// Built-in shader variables: StructuredBuffer<float4x4> unity_PrevObjectToWorldArray; float4x4 unity_MatrixPreviousM; uint unity_BaseInstanceID;
static uint unity_InstanceID;
[shader("closesthit")] void ClosestHitMain(inout RayPayload payload, AttributeData attribs) { float3 localPos = ObjectRayOrigin() + RayTCurrent() * ObjectRayDirection();
#if INSTANCING_ON unity_InstanceID = InstanceIndex() - unity_BaseInstanceID; float3 prevWorldPos = mul(unity_PrevObjectToWorldArray[unity_InstanceID], float4(localPos, 1)).xyz; #else float3 prevWorldPos = mul(unity_MatrixPreviousM, float4(localPos, 1)).xyz; #endif float3 worldPos = WorldRayOrigin() + RayTCurrent() * WorldRayDirection();
payload.velocity = worldPos - prevWorldPos; }
根据 config 参数和 instanceData 自定义结构中的参数,AddInstances 将为命中着色器设置并绑定以下内置结构化缓冲区
unity_PrevObjectToWorldArray
(float4x4) - 当 instanceData 自定义结构中存在 prevObjectToWorld 成员时。unity_RenderingLayerArray
(float) - 当 instanceData 自定义结构中存在 renderingLayerMask 成员时。unity_SHArArray
, unity_SHAgArray
, unity_SHAbArray
, unity_SHBrArray
, unity_SHBgArray
, unity_SHBbArray
, unity_SHCArray
(float4) - 当 config.lightProbeUsage 为 LightProbeUsage.Off(仅环境探测器)、LightProbeUsage.BlendProbes 或 LightProbeUsage.UseProxyVolume(当 config.lightProbeProxyVolume.qualityMode 设置为 LightProbeProxyVolume.QualityMode.Normal 时)时的球谐系数(由环境探测器和光探测器使用)。请注意,AddInstances 不会设置并绑定 unity_ObjectToWorldArray
或 unity_WorldToObjectArray
缓冲区,因为您可以使用 ObjectToWorld()
或 WorldToObject()
HLSL 内部函数在命中着色器中访问光线追踪实例变换矩阵。
您可以使用此函数最多添加 1048575 个光线追踪网格实例。最终的实例数量取决于 startInstance 和 instanceCount 参数。您可以使用 unity_InstanceCount
内置统一变量在 HLSL 中访问实例数量。
如果 config 参数中指定的材质没有将 Material.enableInstancing 设置为 true,则 AddInstances 会抛出 InvalidOperationException。当您添加完所有必需的实例后,请使用 RayTracingAccelerationStructure.Build 或 CommandBuffer.BuildRayTracingAccelerationStructure 在 GPU 上构建加速结构。
此功能除了光线追踪支持外没有任何特殊硬件要求(SystemInfo.supportsRayTracing 必须为 true)。在 DirectX 光线追踪 (DXR) 中,此函数会导致数组中的所有光线追踪实例仅使用着色器表中的一个着色器记录,从而减少渲染线程上将 GPU 资源绑定到命中着色器的 CPU 开销。
其他资源:RayTracingAccelerationStructure.AddInstance、RayTracingAccelerationStructure.RemoveInstance。