尽管其他缓冲区已绑定,但常量缓冲区未绑定? (DirectX12)
Constant Buffer not binding although other buffers are binding? (DirectX12)
所以我有以下函数可以渲染动画实体
void DeferredRenderer::DrawAnimated(ID3D12GraphicsCommandList * clist, std::vector<Entity*> entities)
{
clist->SetPipelineState(sysRM->GetPSO(StringID("animDeferredPSO")));
clist->SetGraphicsRootDescriptorTable(RootSigCBAll1, frame->GetGPUHandle(frameHeapParams.PerFrameCB));
auto boneCBIndex = 0;
for (auto e : entities)
{
//Set start of material texture in root descriptor, binds successfully
clist->SetGraphicsRootDescriptorTable(RootSigSRVPixel1, frame->GetGPUHandle(frameHeapParams.Textures, e->GetMaterial()->GetStartIndex()));
//Binds successfully
clist->SetGraphicsRootDescriptorTable(RootSigCBVertex0, frame->GetGPUHandle(frameHeapParams.Entities, e->GetID()));
// Not binding!
clist->SetGraphicsRootDescriptorTable(RootSigCBAll2, frame->GetGPUHandle(frameHeapParams.BoneCB, boneCBIndex));
DrawAnimated(e->GetMesh(), clist);
boneCBIndex++;
}
}
寄存器 b0(RootSigCBVertex0) 和 b1 (RootSigCBAll1) 的缓冲区绑定但 b2 不绑定(在 NSight 调试器中调试时发现)
我在 AnimationVS.hlsl 中的常量缓冲区如下所示:
cbuffer ConstantBuffer : register(b0)
{
float4x4 worldViewProjection;
float4x4 world;
float4x4 view;
float4x4 projection;
float4x4 shadowView;
float4x4 shadowProjection;
};
cbuffer PerFrame : register(b1)
{
float nearZ;
float farZ;
float2 lightPerspectiveValues;
};
cbuffer PerArmature: register(b2)
{
float4x4 bones[MAX_BONES];
}
float4x4 SkinTransform(float4 weights, uint4 bones)
{
// Calculate the skin transform from up to four bones and weights
float4x4 skinTransform =
bones[bones.x] * weights.x +
bones[bones.y] * weights.y +
bones[bones.z] * weights.z +
bones[bones.w] * weights.w;
return skinTransform;
}
我的根签名似乎与传递的参数匹配,甚至 Visual Studio 图形调试器说 Root 参数已绑定,但不是资源对象本身
我的根签名是这样的
CD3DX12_DESCRIPTOR_RANGE range[5];
//view dependent CBV
range[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
//light dependent CBV
range[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
//G-Buffer inputs
range[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 16, 0);
//per frame CBV
range[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1);
//per bone
range[4].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 2);
CD3DX12_ROOT_PARAMETER rootParameters[5];
rootParameters[0].InitAsDescriptorTable(1, &range[0], D3D12_SHADER_VISIBILITY_VERTEX);
rootParameters[1].InitAsDescriptorTable(1, &range[1], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[2].InitAsDescriptorTable(1, &range[2], D3D12_SHADER_VISIBILITY_ALL);
rootParameters[3].InitAsDescriptorTable(1, &range[3], D3D12_SHADER_VISIBILITY_ALL);
rootParameters[4].InitAsDescriptorTable(1, &range[4], D3D12_SHADER_VISIBILITY_ALL);
知道为什么会发生这种情况吗?
编辑:添加了更多上下文。
所以,事实证明这是我的一个非常愚蠢的错误。
SkinTransfrom
函数有一个float4 bones
参数,而常量缓冲区骨骼矩阵数组也称为bones
。这导致该函数在其范围内使用 float4 bones
,完全无视常量缓冲区。
这也意味着着色器会优化常量缓冲区,即从一开始就不会绑定常量缓冲区。当答案就在我面前时,这几乎让我转了一圈!
以下更改为我修复了它:
float4x4 SkinTransform(float4 weights, uint4 boneIndices) // <-- bone to boneIndices
{
float4x4 skinTransform =
bones[boneIndices.x] * weights.x +
bones[boneIndices.y] * weights.y +
bones[boneIndices.z] * weights.z +
bones[boneIndices.w] * weights.w;
return skinTransform;
}
所以我有以下函数可以渲染动画实体
void DeferredRenderer::DrawAnimated(ID3D12GraphicsCommandList * clist, std::vector<Entity*> entities)
{
clist->SetPipelineState(sysRM->GetPSO(StringID("animDeferredPSO")));
clist->SetGraphicsRootDescriptorTable(RootSigCBAll1, frame->GetGPUHandle(frameHeapParams.PerFrameCB));
auto boneCBIndex = 0;
for (auto e : entities)
{
//Set start of material texture in root descriptor, binds successfully
clist->SetGraphicsRootDescriptorTable(RootSigSRVPixel1, frame->GetGPUHandle(frameHeapParams.Textures, e->GetMaterial()->GetStartIndex()));
//Binds successfully
clist->SetGraphicsRootDescriptorTable(RootSigCBVertex0, frame->GetGPUHandle(frameHeapParams.Entities, e->GetID()));
// Not binding!
clist->SetGraphicsRootDescriptorTable(RootSigCBAll2, frame->GetGPUHandle(frameHeapParams.BoneCB, boneCBIndex));
DrawAnimated(e->GetMesh(), clist);
boneCBIndex++;
}
}
寄存器 b0(RootSigCBVertex0) 和 b1 (RootSigCBAll1) 的缓冲区绑定但 b2 不绑定(在 NSight 调试器中调试时发现)
我在 AnimationVS.hlsl 中的常量缓冲区如下所示:
cbuffer ConstantBuffer : register(b0)
{
float4x4 worldViewProjection;
float4x4 world;
float4x4 view;
float4x4 projection;
float4x4 shadowView;
float4x4 shadowProjection;
};
cbuffer PerFrame : register(b1)
{
float nearZ;
float farZ;
float2 lightPerspectiveValues;
};
cbuffer PerArmature: register(b2)
{
float4x4 bones[MAX_BONES];
}
float4x4 SkinTransform(float4 weights, uint4 bones)
{
// Calculate the skin transform from up to four bones and weights
float4x4 skinTransform =
bones[bones.x] * weights.x +
bones[bones.y] * weights.y +
bones[bones.z] * weights.z +
bones[bones.w] * weights.w;
return skinTransform;
}
我的根签名似乎与传递的参数匹配,甚至 Visual Studio 图形调试器说 Root 参数已绑定,但不是资源对象本身
我的根签名是这样的
CD3DX12_DESCRIPTOR_RANGE range[5];
//view dependent CBV
range[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
//light dependent CBV
range[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
//G-Buffer inputs
range[2].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 16, 0);
//per frame CBV
range[3].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 1);
//per bone
range[4].Init(D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 2);
CD3DX12_ROOT_PARAMETER rootParameters[5];
rootParameters[0].InitAsDescriptorTable(1, &range[0], D3D12_SHADER_VISIBILITY_VERTEX);
rootParameters[1].InitAsDescriptorTable(1, &range[1], D3D12_SHADER_VISIBILITY_PIXEL);
rootParameters[2].InitAsDescriptorTable(1, &range[2], D3D12_SHADER_VISIBILITY_ALL);
rootParameters[3].InitAsDescriptorTable(1, &range[3], D3D12_SHADER_VISIBILITY_ALL);
rootParameters[4].InitAsDescriptorTable(1, &range[4], D3D12_SHADER_VISIBILITY_ALL);
知道为什么会发生这种情况吗?
编辑:添加了更多上下文。
所以,事实证明这是我的一个非常愚蠢的错误。
SkinTransfrom
函数有一个float4 bones
参数,而常量缓冲区骨骼矩阵数组也称为bones
。这导致该函数在其范围内使用 float4 bones
,完全无视常量缓冲区。
这也意味着着色器会优化常量缓冲区,即从一开始就不会绑定常量缓冲区。当答案就在我面前时,这几乎让我转了一圈!
以下更改为我修复了它:
float4x4 SkinTransform(float4 weights, uint4 boneIndices) // <-- bone to boneIndices
{
float4x4 skinTransform =
bones[boneIndices.x] * weights.x +
bones[boneIndices.y] * weights.y +
bones[boneIndices.z] * weights.z +
bones[boneIndices.w] * weights.w;
return skinTransform;
}