在计算最终骨骼矩阵时并行化骨骼矩阵计算是层次结构
Parallelizing the Bone matrix computation when calculating the Final Bone matrix i Hirerachy
ReadNodeHeirarchy 找到给定时间戳的平移、旋转和缩放的插值值,因此每次 Frame 计算这些值并将它们馈送到 GPU 以对每个骨骼进行最终转换。
有没有优化代码的方法?有没有人试图将这个计算转移到 GPU 上?
void Mesh::ReadNodeHeirarchy(float AnimationTime, const aiNode* pNode, const Matrix4f& ParentTransform)
{
string NodeName(pNode->mName.data);
const aiAnimation* pAnimation = m_pScene->mAnimations[0];
Matrix4f NodeTransformation(pNode->mTransformation);
const aiNodeAnim* pNodeAnim = FindNodeAnim(pAnimation, NodeName);
if (pNodeAnim) {
// Interpolate scaling and generate scaling transformation matrix
aiVector3D Scaling;
CalcInterpolatedScaling(Scaling, AnimationTime, pNodeAnim);
Matrix4f ScalingM;
ScalingM.InitScaleTransform(Scaling.x, Scaling.y, Scaling.z);
// Interpolate rotation and generate rotation transformation matrix
aiQuaternion RotationQ;
CalcInterpolatedRotation(RotationQ, AnimationTime, pNodeAnim);
Matrix4f RotationM = Matrix4f(RotationQ.GetMatrix());
// Interpolate translation and generate translation transformation matrix
aiVector3D Translation;
CalcInterpolatedPosition(Translation, AnimationTime, pNodeAnim);
Matrix4f TranslationM;
TranslationM.InitTranslationTransform(Translation.x, Translation.y, Translation.z);
// Combine the above transformations
NodeTransformation = TranslationM * RotationM * ScalingM;
}
Matrix4f GlobalTransformation = ParentTransform * NodeTransformation;
if (m_BoneMapping.find(NodeName) != m_BoneMapping.end()) {
uint BoneIndex = m_BoneMapping[NodeName];
m_BoneInfo[BoneIndex].FinalTransformation = m_GlobalInverseTransform * GlobalTransformation *
m_BoneInfo[BoneIndex].BoneOffset;
}
for (uint i = 0 ; i < pNode->mNumChildren ; i++) {
ReadNodeHeirarchy(AnimationTime, pNode->mChildren[i], GlobalTransformation);
}
}
您的代码是递归的,GPU 非常不擅长 运行 递归代码或循环语句。因此,您必须以 GPU 可以接受它并为您提供更好性能的方式调整您的逻辑。
你实际上混淆了两个不同的问题。
1) 计算所有节点的全局矩阵,必须基于场景图递归。这是一个 CPU 问题而不是 GPU 问题,因为递归是解决此问题的最佳方法。
2) 实际插值和矢量数学。这可以通过使用 SIMD 优化代码来加速,这将为您的所有矢量数学运算提供 4 倍的速度提升。
对于您的问题,我建议使用 SIMD 优化。
注意:我写的内容与您在此处发布的内容非常相似。将 Assimp 和 OpenGLES 用于 iOS & Android。
ReadNodeHeirarchy 找到给定时间戳的平移、旋转和缩放的插值值,因此每次 Frame 计算这些值并将它们馈送到 GPU 以对每个骨骼进行最终转换。 有没有优化代码的方法?有没有人试图将这个计算转移到 GPU 上?
void Mesh::ReadNodeHeirarchy(float AnimationTime, const aiNode* pNode, const Matrix4f& ParentTransform)
{
string NodeName(pNode->mName.data);
const aiAnimation* pAnimation = m_pScene->mAnimations[0];
Matrix4f NodeTransformation(pNode->mTransformation);
const aiNodeAnim* pNodeAnim = FindNodeAnim(pAnimation, NodeName);
if (pNodeAnim) {
// Interpolate scaling and generate scaling transformation matrix
aiVector3D Scaling;
CalcInterpolatedScaling(Scaling, AnimationTime, pNodeAnim);
Matrix4f ScalingM;
ScalingM.InitScaleTransform(Scaling.x, Scaling.y, Scaling.z);
// Interpolate rotation and generate rotation transformation matrix
aiQuaternion RotationQ;
CalcInterpolatedRotation(RotationQ, AnimationTime, pNodeAnim);
Matrix4f RotationM = Matrix4f(RotationQ.GetMatrix());
// Interpolate translation and generate translation transformation matrix
aiVector3D Translation;
CalcInterpolatedPosition(Translation, AnimationTime, pNodeAnim);
Matrix4f TranslationM;
TranslationM.InitTranslationTransform(Translation.x, Translation.y, Translation.z);
// Combine the above transformations
NodeTransformation = TranslationM * RotationM * ScalingM;
}
Matrix4f GlobalTransformation = ParentTransform * NodeTransformation;
if (m_BoneMapping.find(NodeName) != m_BoneMapping.end()) {
uint BoneIndex = m_BoneMapping[NodeName];
m_BoneInfo[BoneIndex].FinalTransformation = m_GlobalInverseTransform * GlobalTransformation *
m_BoneInfo[BoneIndex].BoneOffset;
}
for (uint i = 0 ; i < pNode->mNumChildren ; i++) {
ReadNodeHeirarchy(AnimationTime, pNode->mChildren[i], GlobalTransformation);
}
}
您的代码是递归的,GPU 非常不擅长 运行 递归代码或循环语句。因此,您必须以 GPU 可以接受它并为您提供更好性能的方式调整您的逻辑。
你实际上混淆了两个不同的问题。
1) 计算所有节点的全局矩阵,必须基于场景图递归。这是一个 CPU 问题而不是 GPU 问题,因为递归是解决此问题的最佳方法。
2) 实际插值和矢量数学。这可以通过使用 SIMD 优化代码来加速,这将为您的所有矢量数学运算提供 4 倍的速度提升。
对于您的问题,我建议使用 SIMD 优化。
注意:我写的内容与您在此处发布的内容非常相似。将 Assimp 和 OpenGLES 用于 iOS & Android。