XNA Matrix Optimization and Animated Models

Started by
2 comments, last by max343 11 years, 2 months ago

Hi All, this is my first post so please forgive me if this is the wrong section or misdirected!

Now to get down to business. I have been working on a 3d visualization for a simulation in XNA. The graphics are all implemented and I have

been trying to improve performance. I have isolated that the main performance hog is all the matrix operations done on animated models. (The project is currently CPU Bound)

Specifically this code


 //Compute all of the bone absolute transforms
for (int i = 0, index = 0; i < model.Bones.Count; i++, index++)
{
    model.Bones[i].ComputeAbsoluteTransform();
    model.boneTransforms[index] = model.Bones[i].AbsoluteTransform;
}

//Determine the skin transforms from the skeleton
for (int s = 0; s < model.ModelExtra.Skeleton.Count; s++)
{
    model.skeleton[s] = model.Bones[model.ModelExtra.Skeleton[s]].SkinTransform 
                  * model.Bones[model.ModelExtra.Skeleton[s]].AbsoluteTransform;
}

Even more specifically the compute absolute transform is particularly CPU intensive.


private Matrix _scaleMatrixTemp;
private Matrix _rotationMatrixTemp;
private Matrix _translationMatrixTemp;
private Matrix _transformMatrix;
private Matrix _tempA;
private Matrix _tempB;

/// <summary>
/// Compute the absolute transformation for this bone.
/// </summary>
public void ComputeAbsoluteTransform()
{
   Matrix.CreateScale(ref bindScale, out _scaleMatrixTemp);
   Matrix.CreateFromQuaternion(ref rotation, out _rotationMatrixTemp);
   Matrix.CreateTranslation(ref translation, out _translationMatrixTemp);
   Matrix.Multiply(ref _scaleMatrixTemp, ref _rotationMatrixTemp, out _tempA);
   Matrix.Multiply(ref _tempA, ref _translationMatrixTemp, out _tempB);
   Matrix.Multiply(ref _tempB, ref bindTransform, out _transformMatrix);
   if (Parent != null)
   {
       // This bone has a parent bone
       Matrix.Multiply(ref _transformMatrix, ref Parent.AbsoluteTransform,
              out AbsoluteTransform);
   }
   else
   {   
       // The root bone
       AbsoluteTransform = _transformMatrix;
   }
}

I have read about the benefits of using the ref version of Matrix multiply. But is there something I am missing, this still seems to be the most CPU intensive part of the whole application. Is there something I am missing that can be moved to the GPU? Or is this just the price one has to pay for skinned animations?

Thanks!

Advertisement
You can optimize this bit of code. All those multiplications are of specific matrices, and can be implemented in a faster way than general matrix multiplication.

Okay, thanks for the reply! So you're saying that I should look into some of the algebra behind those multiplications and write a method that takes advantage of their specific properties?

Exactly. For instance, pure scaling and translation have only three meaningful elements in them. You can use this to reduce the number of floating point operations drastically. Only thing to note is to use SIMD operations rather than scalar.

This topic is closed to new replies.

Advertisement