6

OK、私は単純なテクスチャを持つ 80,000 の「ボックス」メッシュを持っています。表示距離を設定し、下の DrawModel 関数に 600 から 1000 を残す、見えるものだけを描画します。また、すべてのコードに対してメモリ テストを行ったところ、"mesh.draw()" で毎秒 30 フレームがオフになります。それほどNEARを取るものは他にありません。何か助けはありますか?

        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();               
            }
        }
4

2 に答える 2

7

あなたが言うように、あなたのパフォーマンスを殺しているのは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 にバッチを何回送信するかということです。CPUを飽和させる前に、フレームごとに数千の*バッチしか送信できないため、「バッチ制限」に達します。(各バッチは、グラフィックス ドライバーの CPU 時間を使い果たします。帯域幅と GPU 時間も使用しますが、CPU 時間が支配的です。)

追加情報については、この回答この回答、およびこのスライド デッキをお読みください。

解決策は、GPU に送信するバッチの数を減らすために、シーンを変更することです (例: いくつかのメッシュ パーツを組み合わせる、いくつかのカリングを実行する、インスタンス化サポートを追加する)。


Drawまた、 andUpdateループで次のようなことを避けるようにしてください。

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

フレームごとに発生するメモリ割り当てを回避するために最善を尽くす必要があります。最終的には高価なガベージ コレクションが発生し、フレーム レートの問題が発生する可能性があります (特に Xbox の場合)。バッファをどこかに保存して再利用してみてください。

于 2011-06-03T04:08:46.037 に答える
3
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 倍以上少なくなります!)

于 2011-06-02T22:20:11.977 に答える