C # XNA with low frame rate

Ok, I have 80,000 "Box" Mesh with simple textures. I set the viewing distance and just draw the ones you can see that leave 600 to 1000 for the DrawModel function below. The problem is that I only get 10 frames per second , and the distance to the screen is crappy. In addition, I checked the memory test for all my code, and "mesh.draw ()" takes 30 frames per second. nothing will be so close anymore. 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(); } } 
+6
source share
2 answers

What kills your performance - as you say - is ModelMesh.Draw . When you draw models, it works as follows:

 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 do you send a packet to the GPU? Because you can only send a few thousand * batches per frame before saturating the processor by clicking "batch limit". (Each batch uses processor time in the graphics driver β€” it also uses some bandwidth and GPU time, but processor time dominates.)

You can read this answer and this answer and this slide panel for more information.

The solution is to change your scene (for example: combine some parts of the grid, perform a selection, add instancing support) to reduce the number of parties sent to the GPU.


In addition, try to avoid such situations in the Draw and Update loops:

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

You should do everything possible to avoid the memory allocation that occurs in each frame, as they will ultimately cause an expensive garbage collection and a potential icon with a frame rate (especially on the Xbox). Try saving the buffer somewhere and reusing it.

+7
source
 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); 

I am not a profiler, but I feel that this line is a pain. Creating and multiplying a matrix is ​​quite expensive! I understand that this code is necessary, so if you cannot pre-calculate these matrices, I would try:

 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); 

This can be faster, since there is no need to copy each matrix onto the stack to transfer parameters ( 20 times less files to copy !)

+3
source

Source: https://habr.com/ru/post/889652/


All Articles