shader - 有没有一种特定的方法可以将数组作为常量缓冲区传递给着色器?
问题描述
在c++中,数组中有一个值,当我将它传递给shader时,数据都是0。有没有具体的方法将数组传递给shader?
这是我设置常量缓冲区的代码
vector<XMFLOAT4X4> finalTransforms = Animator->GetTransforms(_timeDelta);
BoneTransformBuffer.SetData(GraphicDev->GetDeviceContext(), finalTransforms);
auto Transform = BoneTransformBuffer.GetBuffer();
GraphicDev->GetDeviceContext()->VSSetConstantBuffers(1, 1, &Transform);
这是我在着色器中的常量缓冲区
cbuffer cbSkinned : register(b1)
{
float4x4 BoneTransforms[96];
};
解决方案
您的代码片段缺少有关您的类型和支持代码的大量信息,但我的第一个猜测是您应该使用:
BoneTransformBuffer.SetData(GraphicDev->GetDeviceContext(), finalTransforms.data());
此外,除非依赖返回优化,否则这条线vector<XMFLOAT4X4> finalTransforms = Animator->GetTransforms(_timeDelta);
会额外复制所有数据。GetTransforms
剥皮
请注意,对于蒙皮,您通常不需要为每个骨骼提供完整的 4x4 矩阵。蒙皮动画几乎总是使用仿射变换(平移、缩放和旋转),因此您浪费了常量缓冲区中 25% 的空间。
相反,使用:
struct SkinnedConstants
{
XMVECTOR bones[96][3];
};
cbuffer cbSkinned : register(b1)
{
float4x3 BoneTransforms[96];
};
然后你使用这样的东西来设置骨骼数据:
for (size_t i = 0; i < count; i++)
{
#if DIRECTX_MATH_VERSION >= 313
XMStoreFloat3x4A(reinterpret_cast<XMFLOAT3X4A*>(&boneConstant[i]), value[i]);
#else
// Xbox One XDK has an older version of DirectXMath
XMMATRIX boneMatrix = XMMatrixTranspose(value[i]);
boneConstant[i][0] = boneMatrix.r[0];
boneConstant[i][1] = boneMatrix.r[1];
boneConstant[i][2] = boneMatrix.r[2];
#endif
}
HLSL 代码类似于:
float3 Skin(inout VSInputNmTxWeights vin, float3 normal, uniform int boneCount)
{
float4x3 skinning = 0;
[unroll]
for (int i = 0; i < boneCount; i++)
{
skinning += Bones[vin.Indices[i]] * vin.Weights[i];
}
vin.Position.xyz = mul(vin.Position, skinning);
return mul(normal, (float3x3)skinning);
}
请参阅用于DX11 / DX12的XNA Game Studio Stock Effects和 DirectX Tool Kit 。
推荐阅读
- python - 我收到错误消息“没有名为 selenium 的模块”
- anylogic - 随机服务点
- c# - 我们应该总是使用 PipeWriter.GetMemory > Advance > Flush 吗?我们什么时候使用 WriteAsync?
- r - 如何读取每行末尾有额外分隔符导致的空白列的 CSV?
- java - Kotlin JNA 将声明的字段名称设为空列表
- android - Android:重新安装我的应用程序后无法访问我的应用程序创建的文件
- node.js - 使用 NGINX 在 VPS 服务器(ubuntu 16.04)上部署 React 前端和 Express 后端
- javascript - 让 Puppeteer 同时转到不同的链接
- gremlin - 如何通过in-edge属性值大于out-edge属性值来查询gremlin顶点
- angular - PrimeNG Message & Toast 在组件中工作但不在服务中