Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Batch and performance confusion

Started by Tasaq Sep 5, 2012 at 8:21 AM 3 replies 1.6k views
Original Post
Tasaq
Tasaq
Hi everyone,
I would like to know how to optimise things, and first thing I would like to ask about are batches. As far as I understand for folowing pseudocode:
[source lang="csharp"] foreach (Model model in modelList)
{
foreach (ModelMesh mesh in model.Meshes)
{

//shader variables here

foreach (ModelMeshPart part in mesh.MeshParts)
{
part.Effect = effect;
}
effect.Techniques[0].Passes[0].Apply();
mesh.Draw();
}
}[/source]
mesh.Draw() is sending single btach to gpu right? Which means when my model, for instance a car, has many parts (like, wheels, doors, side mirrors) I send a lot of batches.
My first question is if I can put those parts together in the code(I would like to open doors, rotate the wheels so I don't want to export them from 3d editting program as one mesh)? We could use single batch for doors, body, hood and other body parts because they share same material, we set values in the shader once for all of those parts and send single batch so we save a lot.

Another question I would like to ask is how I can perform instancing in XNA? And again, by sending it in single batch(like for vegetation or decals).
I have read Batch, Batch, Batch:” What Does It Really Mean?" pdf but I am still confused rolleyes.gif

Aside from batches, I have another problem with culling. It's kinda working, because when i look camera the other way the object is positioned I see that fps go up. But when I go far away from objects (so far the object is behind far clip) fps doesn't change or change very little compared to simple if(Vector3.Distance(camera,object) < farPlane) continue; which works fine. Does it also has to do with batches? (which are send, even though they are not beeing drawn?). Also does sorting front to back gives a speed boost for opaque objects?
quiSHADgho
quiSHADgho
For instancing with XNA look into this sample:
http://xbox.create.m...mesh_instancing
The short explanation is you have to store all transformation values for all instances and put them into a buffer then make one draw call per meshpart.

Batching can also mean putting together multiple vertexdata instances like terrain patches and draw them at once to max out the vertex buffer vertex count limit.


Aside from batches, I have another problem with culling. It's kinda working, because when i look camera the other way the object is positioned I see that fps go up. But when I go far away from objects (so far the object is behind far clip) fps doesn't change or change very little compared to simple if(Vector3.Distance(camera,object) < farPlane) continue; which works fine. Does it also has to do with batches? (which are send, even though they are not beeing drawn?). Also does sorting front to back gives a speed boost for opaque objects?


I dont't know if you wrote some explicit culling code but looking away from objects is not really culling. It's just your graphics card noticing that the objects are not visible and theres no need to draw them so they are not drawn. What you probably want is something like view frustum culling. This is done before the objects are drawn. So for each object you have to check if it is visible and if not then don't put it into the instancing buffer.
The need to sort the objects depends on what kind of game you trying to make. Sorting it from front to back lowers the overdraw in the pixelshader but todays hardware is capable of doing early z-cull so the pixels are culled before the pixel is processed. If you have really dense scenes with thousands of objects overdraw is an issue but in those scenes you also need alot of cpu cycles to sort the geometry. I would save them and invest them in the game logic.
kauna
kauna
You'll need to look the loop from the other point of view. You may loop through your meshes in the fashion you have described, but instead of drawing the meshes you put the required transforms / materials in separate buckets and after that issue the instanced draw command so that for each material/mesh combination there is only one draw command. In my project I draw practically all objects using instanced drawing commands.

Otherwise, if your artist isn't able to produce objects with few meshes you could collapse the non-animated parts of the mesh. However, I'd implement first instancing and then see if there is something wrong with the art work.

Cheers!
Tasaq
Tasaq

For instancing with XNA look into this sample:
http://xbox.create.m...mesh_instancing
The short explanation is you have to store all transformation values for all instances and put them into a buffer then make one draw call per meshpart.


That will do for me, gonna experiment more

The need to sort the objects depends on what kind of game you trying to make. Sorting it from front to back lowers the overdraw in the pixelshader but todays hardware is capable of doing early z-cull so the pixels are culled before the pixel is processed. If you have really dense scenes with thousands of objects overdraw is an issue but in those scenes you also need alot of cpu cycles to sort the geometry. I would save them and invest them in the game logic.

Ok I got shell sorting for transparent objects so I asked out of curiosity because I could add sorting for opaque no problem

You'll need to look the loop from the other point of view. You may loop through your meshes in the fashion you have described, but instead of drawing the meshes you put the required transforms / materials in separate buckets and after that issue the instanced draw command so that for each material/mesh combination there is only one draw command. In my project I draw practically all objects using instanced drawing commands.

Otherwise, if your artist isn't able to produce objects with few meshes you could collapse the non-animated parts of the mesh. However, I'd implement first instancing and then see if there is something wrong with the art work.

Cheers!


Wow thanks, never tought of that Interesting Idea, and should save a lot But it will require some changes in engine, but it's worth it. If it's for artists I am also one of them so I can get what I want and explain others what to do
kauna
kauna
You may also look into the Frostbyte engine slides. They store all the their transforms + some extra data inside a generic float buffer object. I implemented it in a similar way. So before drawing I loop through all the meshes and store the required transform data (+some other data required by the mesh) inside the buffer object. The advantage is that the buffer is discarded, mapped and unmapped only once per frame. It also contains all the transforms needed for the frame rendering, so there will be much less of hassling with constant buffers.

Using it requires vertex shader texture fetch, but that shouldn't affect the performance. At least I couldn't measure any performance penalties on HD5xxx based product.

[edit] I'm not sure if the buffer objects are available on XNA

Cheers!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.