c # XNA низкая частота кадров - PullRequest
6 голосов
/ 02 июня 2011

Хорошо, у меня есть 80000 "Box" Mesh с простыми текстурами. Я установил расстояние просмотра и рисую только те, которые вы видите, которые оставляют от 600 до 1000 для функции DrawModel ниже. Вероятность того, что я получу только 10 кадров в секунду иМое расстояние просмотра дрянное. Кроме того, я проверил память на весь мой код, и "mesh.draw ()" отключает 30 кадров в секунду.ничто иное не так близко.Любая помощь?

        private void DrawModel(MeshHolder tmpMH)
        {          
            Model tmpDrawModel = (Model)_Meshs[tmpMH.MeshFileName];
            Matrix[] transforms = new Matrix[tmpDrawModel.Bones.Count];
            tmpDrawModel.CopyAbsoluteBoneTransformsTo(transforms);
            foreach (ModelMesh mesh in tmpDrawModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {

                    effect.LightingEnabled = false;

                    effect.TextureEnabled = true;
                    effect.Texture = (Texture2D)_Textures[tmpMH.GetTexture(Count)]; 



                    effect.View = _MainCam.View;
                    effect.Projection = _projection;
                    effect.World =
                         transforms[mesh.ParentBone.Index] *
                        Matrix.CreateFromYawPitchRoll(tmpMH.Rotation.Y, tmpMH.Rotation.X, tmpMH.Rotation.Z) *
                        Matrix.CreateScale(tmpMH.Scale) *
                        Matrix.CreateTranslation(tmpMH.Position);
                }

                    mesh.Draw();               
            }
        }

Ответы [ 2 ]

7 голосов
/ 03 июня 2011

Что убивает ваше выступление - как вы говорите - это ModelMesh.Draw.Когда вы рисуете модели, это работает следующим образом:

for each frame
  for each Model
    for each ModelMesh // you call Draw(), which does:
      for each ModelMeshPart
        for each Effect
          for each EffectPass
            Draw some triangles // sends a batch of instructions to the GPU

Итак, вопрос: сколько раз каждый кадр вы отправляете серию в GPU?Потому что вы можете отправлять только несколько тысяч * пакетов за кадр, прежде чем загружать процессор - достигнув «предела пакета».(Каждый пакет использует процессорное время в графическом драйвере - он также использует некоторую пропускную способность и время графического процессора, но процессорное время доминирует.)

Вы можете прочитать этот ответ и этот ответ и эту слайд-деку для получения дополнительной информации.

Решение состоит в том, чтобы изменить вашу сцену (например: объединить несколько частей сетки, сделать несколько отбраковок, добавить поддержку создания экземпляров), чтобы уменьшитьколичество пакетов, которые вы отправляете в графический процессор.


Также старайтесь избегать подобных вещей в цикле Draw и Update:

Matrix[] transforms = new Matrix[tmpDrawModel.Bones.Count];

Вы должныдействительно старайтесь избегать выделения памяти, которое происходит в каждом кадре, поскольку в конечном итоге это приведет к дорогостоящей сборке мусора и, возможно, к перебоям в частоте кадров (особенно в Xbox).Попробуйте где-то хранить свой буфер и использовать его повторно.

3 голосов
/ 03 июня 2011
effect.World =
    transforms[mesh.ParentBone.Index] *
    Matrix.CreateFromYawPitchRoll(
      tmpMH.Rotation.Y, tmpMH.Rotation.X, tmpMH.Rotation.Z) *
    Matrix.CreateScale(tmpMH.Scale) *
    Matrix.CreateTranslation(tmpMH.Position);

Я не профилировщик, но я чувствую, что эта линия - боль.Создание и умножение матриц довольно дорого!Я понимаю, что этот код необходим, поэтому, если вы не можете предварительно вычислить эти матрицы, я бы попробовал:

Matrix pitch, scale, translation, temp1, temp2;

Matrix.CreateFromYawPitchRoll(
    tmpMH.Rotation.Y, tmpMH.Rotation.X, tmpMH.Rotation.Z, out pitch);
Matrix.CreateScale(ref tmpMH.Scale, out scale);
Matrix.CreateTranslation(ref tmpMH.Position, out translation);
Matrix.Multiply(ref transforms[mesh.ParentBone.Index], ref pitch, out temp1);
Matrix.Multiply(ref temp1, ref scale, out temp2);
Matrix.Multiply(ref temp2, ref translation, out effect.World);

Это может быть быстрее, поскольку нет необходимости копировать каждую матрицу в стеке для передачи параметров ( копий в 20 раз меньше !)

...