Lostlogic

Ok, I have a simple mesh loaded that contains 24 faces. I have a loop that draws 144 of these boxes on-screen like so:

for (int i = -(mapwidth / 2); i < (mapwidth/2); i++)
{
for (int j = -(mapheight/2); j < (mapheight/2); j++)
{
modelPosition = new Vector3((i * 10.0f)+5.0f, 0.0f, (j * 10.0f));
DrawModel(myModel);
}
}

I noticed that if I have only one model in view (the camera is zoomed way in) or I show the entire grid of objects the time elapsed between frames does not change. The time elapsed between frames does change if I increase or decrease the number of objects drawn though. This leads me to believe that the framework is drawing every object whether or not it is visible. Can someone shed light on how to avoid this performance problem

Another concern I have is that when I draw 20x20 of these objects (400) I get about 16 FPS on my machine. Thats only 9600 faces per frame and at 16 FPS that equates to a pipeline of about 154k polys a second. I have a rig setup with: 3.2ghz P4, 2 GB RAM, Geforce 6800 GT video card. Seems kinda slow doesn't it



Re: XNA Framework How to only draw visible meshes? Performance problems.

Dodger_

The framework is not in charge of whether a visible object should be drawn. You tell it what to draw and it will send it to the video card. My guess, though, is that state changes are what is killing your performance not polygon count. You didn't include the source for DrawModel() so it's hard to say what you're doing exactly.  Debug builds are also slower than Release, so make sure you're profiling it under Release.




Re: XNA Framework How to only draw visible meshes? Performance problems.

Lostlogic

Dodger_ wrote:
The framework is not in charge of whether a visible object should be drawn. You tell it what to draw and it will send it to the video card. My guess, though, is that state changes are what is killing your performance not polygon count. You didn't include the source for DrawModel() so it's hard to say what you're doing exactly. Debug builds are also slower than Release, so make sure you're profiling it under Release.


Here's the draw model code and I am building the Release version:

protected void DrawModel(Model ModelToDraw)
{
//Copy any parent transforms
Matrix[] transforms = new Matrix[ModelToDraw.Bones.Count];
ModelToDraw.CopyAbsoluteBoneTransformsTo(transforms);

//Draw the model, a model can have multiple meshes, so loop
foreach (ModelMesh mesh in ModelToDraw.Meshes)
{
//This is where the mesh orientation is set, as well as our camera and projection
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] *
Matrix.CreateRotationY(modelRotation) *
Matrix.CreateTranslation(modelPosition) *
Matrix.CreateScale(modelScale);

effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f);
}
//Draw the mesh, will use the effects set above.
mesh.Draw();
}
}





Re: XNA Framework How to only draw visible meshes? Performance problems.

ClydeCoulter

For this reason, I have started 2 projects. One for two dimensional layout of a scene, the other for 3 dimensional.

Now, when I say 2 dimensional, I don't mean 2d game but a layout like a landscape/terrain where all objects are more a less laid out north/south/east/west. But an outerspace game is fully 3 dimensional in the the player can go up/down too.

The projects are Quadtree (landscape type) and Octtree (outerspace type). They are functional in that they do cull out objects that are not visible on the screen. They are extendable in that you get the source code (to modify at will) and also that they provide a base class that itself is derrived from DrawableGameComponent. This base class allows you to draw whatever you like when visible, but it's update get called each frame. They also handle drawing models for you when visible.

Quadtree:

http://www.codeplex.com/quadtreeload

Octtree

http://hosted.filefront.com/ClydeCoulter

They both come with the source for a test game that demonstrate some of what you can do with them. The Quadtree project also comes with a tutorial on creating heightmaps and textures for them.






Re: XNA Framework How to only draw visible meshes? Performance problems.

Lostlogic

ClydeCoulter wrote:

For this reason, I have started 2 projects. One for two dimensional layout of a scene, the other for 3 dimensional.

Now, when I say 2 dimensional, I don't mean 2d game but a layout like a landscape/terrain where all objects are more a less laid out north/south/east/west. But an outerspace game is fully 3 dimensional in the the player can go up/down too.

The projects are Quadtree (landscape type) and Octtree (outerspace type). They are functional in that they do cull out objects that are not visible on the screen. They are extendable in that you get the source code (to modify at will) and also that they provide a base class that itself is derrived from DrawableGameComponent. This base class allows you to draw whatever you like when visible, but it's update get called each frame. They also handle drawing models for you when visible.

Quadtree:

http://www.codeplex.com/quadtreeload

Octtree

http://hosted.filefront.com/ClydeCoulter

They both come with the source for a test game that demonstrate some of what you can do with them. The Quadtree project also comes with a tutorial on creating heightmaps and textures for them.



How does that really show me how to load 3D "tiles" and stitch them together in a performant manner Does anyone know of any resource for doing such a thing





Re: XNA Framework How to only draw visible meshes? Performance problems.

Lostlogic

Update:

I removed the:

effect.EnableDefaultLighting();

Call from each loop and it about doubled my frame rate. I'm still getting what I would consider to be horrible frame rates though. Is there an efficient way to draw the same mesh object multiple times





Re: XNA Framework How to only draw visible meshes? Performance problems.

Dodger_

Lostlogic wrote:

How does that really show me how to load 3D "tiles" and stitch them together in a performant manner Does anyone know of any resource for doing such a thing

He's answering the first question you posed in your post. Quadtrees(more for 2D areas or where height is not a factor) or octtrees are used for arranging objects in your scene in a hierarchy that can be intersected with your frustum to only draw the visible objects.

From what I can see of DrawModel, you've got a lot of potential for repetitive calculation. Why do you need to calculate the projection and view matrices for every effect, for every mesh in the model Are you sure the model you're using only has 1 mesh and 1 effect




Re: XNA Framework How to only draw visible meshes? Performance problems.

inthefields

Let me point you into two directions.

Scene Management and Culling of Objects

As was already pointed out there are several ways to manage culling of objects in 3D Applications. Instead of giving you some crash course of doubtful merit let me advise you to look up a few terms: scenegraph, hierarchical scenegraph, binary space partioning (bsp), quadtree, octree, portal engine. As a starter you might want to read the following article about scene graphs : http://www.realityprime.com/scenegraph.php.

Avoid calculating things at runtime

When it comes to performance calculating as much as possible before entering the rendering loop and / or trying to minimize what is calculated in each frame is pretty vital. I am not saying that all your code calculates too much in each frame (i.e. I don't mean to criticize you), yet in the two code snippets you posted you do a few things in each frame which could be done before (or when changes call for a re-calculation).

For instance

  • the View Matrix inside your DrawModel() method. The View Matrix will only change once per frame (if at all). Still you re-calculate it for every model you render. Assuming your Model contains only one ModelMesh, rendering 20x20 Models results in 400 x calculating the View Matrix. Whether the view (i.e. the camera) changes or not.
  • the same holds true for the Projection Matrix (which changes even less frequently than the View Matrix, i.e. when your client's aspect ratio changes)
  • in every frame you re-calculate the position of your boxes. Why not do that before even entering the game loop (for instance inside some Initialize() method)

I am not saying that this will solve your performance issues (object culling will do a lot more for you there), yet for some types of calculations (for instance calculating square roots) evading recalculation can have a tremendous impact on the performance. Very often making use of so called Look-Up tables are a very simple, yet very effective tool.





Re: XNA Framework How to only draw visible meshes? Performance problems.

Lostlogic

I am using mesh code taken from a different example so I'm guessing there is tons of waste in it. I'm brand new to C# and XNA so I'm a bit at the mercy of the samples I've pulled from to date. I understand how to cull faces and objects from rendering that are not in view but was asking if XNA gives you any tools for doing such.

Now, on the topic of drawing models. Do you know of any examples that show how to instance meshes in a quick fashion I'm thinking there must be a way to do it with vertex shaders or something of some speed





Re: XNA Framework How to only draw visible meshes? Performance problems.

Lostlogic

inthefields wrote:

Let me point you into two directions.

Scene Management and Culling of Objects

As was already pointed out there are several ways to manage culling of objects in 3D Applications. Instead of giving you some crash course of doubtful merit let me advise you to look up a few terms: scenegraph, hierarchical scenegraph, binary space partioning (bsp), quadtree, octree, portal engine. As a starter you might want to read the following article about scene graphs : http://www.realityprime.com/scenegraph.php.

Avoid calculating things at runtime

When it comes to performance calculating as much as possible before entering the rendering loop and / or trying to minimize what is calculated in each frame is pretty vital. I am not saying that all your code calculates too much in each frame (i.e. I don't mean to criticize you), yet in the two code snippets you posted you do a few things in each frame which could be done before (or when changes call for a re-calculation).

For instance

  • the View Matrix inside your DrawModel() method. The View Matrix will only change once per frame (if at all). Still you re-calculate it for every model you render. Assuming your Model contains only one ModelMesh, rendering 20x20 Models results in 400 x calculating the View Matrix. Whether the view (i.e. the camera) changes or not.
  • the same holds true for the Projection Matrix (which changes even less frequently than the View Matrix, i.e. when your client's aspect ratio changes)
  • in every frame you re-calculate the position of your boxes. Why not do that before even entering the game loop (for instance inside some Initialize() method)

I am not saying that this will solve your performance issues (object culling will do a lot more for you there), yet for some types of calculations (for instance calculating square roots) evading recalculation can have a tremendous impact on the performance. Very often making use of so called Look-Up tables are a very simple, yet very effective tool.


Thanks inthefields for the source information.

I am aware of how to get CPU gains by doing lookups, hashes, etc. but am not versed in the area of GPU optimization. Is the GPU processing the matrix math in the code I posted or the CPU One problem I'm having is I'm not sure what is impacting the GPU and what is impacting the CPU. I know I can perform 400 matrix multiplications per frame with no noticeable impact to the CPU but am not aware of what that causes for the GPU. Any insight to this

Maybe someone can save me lots of trouble by answering this question: Are the mesh routines provided by XNA too inefficient for use in drawing many (hundreds) objects per frame





Re: XNA Framework How to only draw visible meshes? Performance problems.

ClydeCoulter

If you are asking whether the Model class checks for visibility (using the matrices provided to the effect), then it would appear not since it doesn't matter whether you see them all or one on the screen, yet there is no impact on framerate.

Another means will be necessary to cull the models (or down to the mesh/meshparts) as far a visiblilty goes.

Anyone from else or from MS know the answer to this question






Re: XNA Framework How to only draw visible meshes? Performance problems.

inthefields

@Lostlogic

"Is the GPU processing the matrix math in the code I posted or the CPU "

If you mean calculating the view / projection / translation matrix: the Matrix math is processed on the CPU. Those matrices are then sent to the Shader Pipeline where they are applied to the vertex buffer (which is also supplied to the Shader Pipeline).

"One problem I'm having is I'm not sure what is impacting the GPU and what is impacting the CPU."

All you need to be always aware of is that XNA completely bases its rendering on the Shader Pipeline. From a simplistic point of view this means that you send a bucket full of vertices to a shader program which then applies the logic defined in it to those vertices. Shader Programs run on the GPU, consequently the Matrix you pass to the Shader Pipeline will be applied to every vertex you send to the Shader Pipeline. In other words, while computing the Matrix happens on the CPU, applying the matrix to the vertices will happen on the GPU. That being said ...

"Are the mesh routines provided by XNA too inefficient for use in drawing many (hundreds) objects per frame "

They are as efficient as any rendering of objects in the Shader Pipeline will get. In other words, once the Vertices and needed parameters (like for instance the View Matrix) are passed to the Shader Pipeline XNA (or the .NET Framework for that matter) are no longer involved in rendering. This is one aspect a lot of people tend to overlook in their (very often almost religious) misbelief that managed 3D applications are slow. So, ultimately, the rendering will always be as fast as your graphics card processes the Shader Pipeline and as efficient as the corresponding Shader Program handles the whatever it is supposed to do with the vertices and pixels.

I hope this clears some things up for you - plus, I hope I am not completely off track with what I just put down - I am far from being a 3D programming guru ;)





Re: XNA Framework How to only draw visible meshes? Performance problems.

Nick Darnell

Hey ClydeCoulter, is your Octree's sector size what it divides everything into (and is constant) or is that only the initial sector size, and then it subdivides as needed



Re: XNA Framework How to only draw visible meshes? Performance problems.

RivieraKid

20 * 20 = 400 draw calls = slow.

simple as that.

you need to use geometry instancing. This involves using 2 data streams. 1 stream contains all your matrices(1 for each instance) and the other contains your model. Google for more info and look here

http://msdn.microsoft.com/library/default.asp url=/library/en-us/directx9_c/Efficiently_Drawing_Multiple_Instances_of_Geometry.asp





Re: XNA Framework How to only draw visible meshes? Performance problems.

ClydeCoulter

Nick Darnell,

The sectorSize is the smallest that it will divide the whole area into at the lowest level nodes (leaf nodes).  The culling takes place at that level.