如果我们要更新常量缓冲区的结构包含一个向量, 只使用copyMemory或memcpy与struct starting指针和struct的大小,不会复制矢量数据,是不是?
struct PerObjectCB {
XMFLOAT4X4 World;
XMFLOAT4X4 WorldInvTranspose;
XMFLOAT4X4 TexTransform;
Material Mat;
vector<XMFLOAT4X4> BoneTransforms;
};
PerObjectCB Data = {.,.,., ..., {/*BoneTransforms data*/}};
ID3D11Buffer* mBuffer;
ID3D11_BUFFER_DESC desc = {...};
device->CreateBuffer(&desc, 0, &mBuffer);
D3D11_MAPPED_SUBRESOURCE mappedResource;
dc->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
CopyMemory(mappedResource.pData, &Data, sizeof(Data));
dc->Unmap(mBuffer, 0);
我将这些更新常量缓冲区代码放入模板类中,然后我可以使用此类来管理更新常量缓冲区,但是当我遇到动画数据向量时,我使用cout&lt;&lt; sizeof(向量&lt; XMFLOAT4X4&gt; BoneTransforms),无论我在向量中放入多少数据,这个向量的大小总是12,我猜结构只存储向量的起始地址,真正的数据是在其他地方。如果这是真的,我该如何处理?
我是否真的必须放弃我为常量缓冲区管理编写的模板类,并专门为更新数组类型数据编写另一个函数?
答案 0 :(得分:0)
所以问题是std::vector
不是POD(普通旧数据)。
struct PerObjectCB {
XMFLOAT4X4 World;
XMFLOAT4X4 WorldInvTranspose;
XMFLOAT4X4 TexTransform;
Material Mat;
vector<XMFLOAT4X4> BoneTransforms;
};
这将是sizeof(XMFLOAT4X4) * 3 + sizeof(Material) + sizeof(std::vector)
。它与BoneTransforms.size() * sizeof(XMFLOAT4X4)
没有任何关系。
如果您要在此CB中发送骨骼变换,则需要选择最大骨骼尺寸&#39;
struct PerObjectCB {
XMFLOAT4X4 World;
XMFLOAT4X4 WorldInvTranspose;
XMFLOAT4X4 TexTransform;
Material Mat;
XMFLOAT4X4 BoneTransforms[MAX_BONES];
};
请注意,您不太可能需要对骨骼进行非仿射变换,因此您应该使用XMFLOAT4X3来节省内存,更重要的是传输带宽
例如,在DirectX Tool Kit中,SkinnedEffect
着色器的最大骨骼数为72.它使用的CB如下所示:
struct SkinnedEffectConstants
{
XMVECTOR diffuseColor;
XMVECTOR emissiveColor;
XMVECTOR specularColorAndPower;
XMVECTOR lightDirection[IEffectLights::MaxDirectionalLights];
XMVECTOR lightDiffuseColor[IEffectLights::MaxDirectionalLights];
XMVECTOR lightSpecularColor[IEffectLights::MaxDirectionalLights];
XMVECTOR eyePosition;
XMVECTOR fogColor;
XMVECTOR fogVector;
XMMATRIX world;
XMVECTOR worldInverseTranspose[3];
XMMATRIX worldViewProj;
XMVECTOR bones[SkinnedEffect::MaxBones][3];
};
DGSLEffect
蒙皮着色器使用五个不同的CB,其中一个包含骨骼:
// Slot 4
struct BoneConstants
{
XMVECTOR Bones[DGSLEffect::MaxBones][3];
};
最初的VS Starter Kit DGSL蒙皮着色器支持59块骨骼。
你可能会问,为什么72?
这是因为借用XNA Game Studio 4的DirectX Tool Kit中的内置着色器支持Direct3D Feature Level 9.1硬件。在内部,这些着色器使用vs_2_0
配置文件,该配置文件需要256个向量常量。 72块骨头占据了其中的216块,剩下的常量将其推高到242,这样就可以为10级实施提供十几个。
如果您需要功能级别10.0或更高版本的硬件,则可以将其扩大而不会对性能产生太大影响。请记住,CB的总大小会影响更新的成本。