2016-09-14 7 views
1

ReadNodeHeirarchyはtranslateの補間値を見つけて&スケールを与えられたTimeStampで回転させるので、フレームごとにこれらの値を計算するたびに各骨の最終変換。 コードを最適化する方法はありますか?誰かがこの計算を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); 
     } 
    } 

答えて

1

あなたのコードは、再帰的であるとGPUは、再帰的なコードまたはループ・ステートメントを実行するには非常に悪いです。したがって、GPUがそれを受け取り、より良いパフォーマンスを得るような方法でロジックを調整する必要があります。

実際には2つの問題が混乱しています。

1)シーングラフに基づいて再帰的でなければならないすべてのノードのグローバルマトリックスを計算する。これはCPUの問題であり、GPUの問題ではありません。

2)実際の補間とベクトル演算。これは、SIMD最適化コードを使用することでスピードアップすることができます。このコードは、すべてのベクトル演算の4倍の速度向上をもたらします。

問題については、SIMDの最適化を使用することをお勧めします。

注:ここに投稿した内容とよく似たものを書いています。 iOS用にAssimpとOpenGLESを使用する& Android。

+0

SIMD操作用サードパーティライブラリを使用していますか? 。 SIMDに最適化されていると思われる行列乗算のためにglmを使用しています – surya

+0

GLMはSIMDには問題ありませんが、GLMよりもはるかに高速なアップルのGLKライブラリに由来する独自のSIMD最適化バージョンを使用しました。メッシュをスキンでレンダリングするには、GPUのスキニングを使用しています。つまり、CPUですべての補間を行い、すべてのボーンのグローバルマトリックスを均一な配列で送信します。 – codetiger

+0

ええ、私は同じことをしますが、ローエンドのQualComチップでテクスチャの原因として送信します。彼らは240のユニフォームしか持っていません。 – surya

関連する問題