Ok, I have 80,000 "Box" Mesh with simple textures I have set a view distance and only draw the ones you can see which leave 600 to 1000 for the DrawModel function belowe The problume is I only get 10 frame per second and my view distance is crappy Also, I have done memory test to all my code and the "mesh.draw()" takes 30 Frame per second off. nothing else take NEAR that much. Any help?
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();
}
}
What is killing your performance - as you say - is ModelMesh.Draw
. When you draw models, it works like this:
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
So the question is: how many times each frame are you sending a batch to the GPU? Because you can only send a few thousand* batches per frame before you saturate the CPU - hitting the "batch limit". (Each batch uses up CPU time in the graphics driver - it also uses some bandwidth and GPU time, but CPU time dominates.)
You may want to read this answer and this answer and this slide deck for additional information.
The solution is to modify your scene (eg: combine some mesh parts, do some culling, add instancing support) to reduce the number of batches you are sending to the GPU.
Also, try to avoid things like this in your Draw
and Update
loop:
Matrix[] transforms = new Matrix[tmpDrawModel.Bones.Count];
You should really do your best to avoid memory allocations that happen each frame - as they will eventually cause an expensive garbage collection and potentially a frame-rate hiccup (especially on Xbox). Try to store your buffer somewhere and reuse it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With