在DirectX12中使用Instancing
当我们需要绘制大量同一种几何物体时,可以使用instancing,一次将所需要的绘制信息全部传输给GPU,使其可以批量绘制同一种几何物体,提高绘制的效率。要使用instancing,首先要对shader代码进行调整:
struct InstanceData
{
float4x4 world;
float4x4 invWorld;
float4x4 worldViewProj;
uint materialIndex;
uint objPad0;
uint objPad1;
uint objPad2;
};
StructuredBuffer<InstanceData> gInstanceData : register(t0, space1);
gInstanceData是一个StructuredBuffer,相当于我们把用到的object const buffer组合在一起,而在绘制过程具体的索引index则可以利用shader提供的SV_InstanceID
关键字取得。还有一点,我们在vertex shader阶段取得的materialIndex,它对每个绘制的instance来说是个常量,因此是不希望经过插值阶段再传给pixel shader的,这里也可以利用shader提供的nointerpolation
关键字进行处理:
struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float4 Color : COLOR;
float2 UV : TEXCOORD0;
// nointerpolation is used so the index is not interpolated
// across the triangle.
nointerpolation uint MatIndex : MATINDEX;
};
VertexOut VS(VertexIn vin, uint instanceID : SV_InstanceID)
{
...
}
在CPU层我们需要调整一下根签名的创建,同时在绘制同一种几何物体的代码前设置正确的srv:
rootParams[1].InitAsShaderResourceView(0, 1);
...
mCommandList->SetGraphicsRootShaderResourceView(1, res.mObjectConstBuffer->GetGPUVirtualAddress());
最后,进行绘制:
mCommandList->DrawIndexedInstanced(object->mIndexCount, object->mInstanceCount, object->mStartIndexLocation, object->mBaseVertexLocation, 0);
如果你觉得我的文章有帮助,欢迎关注我的微信公众号(大龄社畜的游戏开发之路)-