Improving Performance

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
HTAPAWASO
Gnoblar
Posts: 16
Joined: Tue Jul 02, 2013 2:15 pm

Improving Performance

Post by HTAPAWASO »

I'm looking for some advice for improving the performance in my game.

Included is an image to make it clearer what I'm talking about:
Image

As you can see, the batch count is very high, even with so few units on the field. There are two main problems I want to address, if possible.

First up is the hexes on the ground. Each of these is currently one batch, and one entity. The same mesh is used for all of them, but each one creates a copy of the material file so that I can manipulate the image used (as you can see, some have different coloured borders to represent certain things, or are less transparent).
In addition to this functionality, it is important to be able to tell when the mouse is intersecting a hex. Currently I use the code in the wiki for raycasting to the polygon level, which works very well.
The hexes never need to move.
My question is, is there a way to group all the hexes into one batch, without compromising these features? (I don't mind implementing them in a different way if necessary). My understanding of static geometry is that I would not be able to tell which individual tile the mouse was intersecting, which is not OK.


Anyway, the hexes account for 60 batches. Almost all of the rest come from the skeletons and the weapons. With shadows enabled, each skeleton is 5 batches, and each weapon is 3. With shadows off, it is 4 and 2. What I don't understand is why? When I load robot.mesh, it is also 6 batches. Is there any way to reduce this? What causes a mesh to use more than one batch?
Instancing the skeletons/weapons isn't really a solution, as in the final game all the units will be different, I'm just using the one mesh now for testing.


Thanks for any help or advice you can offer.
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: Improving Performance

Post by c6burns »

A batch operation is the rendering of a single set of vertices/indices with a single material. So in your modelling program, if you have 3 meshes with 3 materials that combine to make your character then it is going to take 3 batches to render. So some of the work of reducing batch count has to happen in your tools prior to export, by combining materials and even meshes if necessary.

In terms of ideas for reducing the batch count of the hex grid, you could always render the entire set of black hexes in a single batch, and then draw the colored hexes in additional batches over that. There are a few other ways to go, but I think that might be the simplest to implement.
User avatar
areay
Bugbear
Posts: 819
Joined: Wed May 05, 2010 4:59 am
Location: Auckland, NZ
x 69

Re: Improving Performance

Post by areay »

c6burns wrote: In terms of ideas for reducing the batch count of the hex grid, you could always render the entire set of black hexes in a single batch, and then draw the colored hexes in additional batches over that. There are a few other ways to go, but I think that might be the simplest to implement.
Using c6burns' method above is going to be the best overall; it's easy and you'll only end up with as many batches as you have variants of hex-style. The only downside I can see is that you might have problems if you're trying to do a hex with a combination of effects on it, like a thick-outlined, 50% transparent, segmented outline. With this method the top-most layer would override everything else.

If this hex grid is the thing that defines your game, that the user is always going to paying attention to, and you don't mind investing heaps of time into it here's what I'd do. Do the entire grid as a single Ogre::ManualObject!!! Variations in the grid would be handled by redrawing the MO with different parameters for the cells and graphical effects would be achieved by passing different UV and vertex colour values through to your custom shader. Aaaaaaawwww yeah.

I'm having fun with this so I'm going to pollute your mind with some implementation ideas.

You'd start by creating a whole class to handle the grid (although you're probably already doing this), it'd have setter/getter methods for the various settings that any given hex 'cell' might have (a setter would trigger a redraw). Each level you'd tell the grid to generate a world of cells based on a seed or some other settings like "NumberOfCells" and "CellPattern". You'd create your single Ogre::ManualObject then for each cell you'd call a createCell(int ID, Ogre::Vector3 location) function which would add the vertices for a single cell to your class' MO in a similar style to this http://www.ogre3d.org/tikiwiki/tiki-ind ... e=Circle3D . In that linked example you can see how to change the thickness of the line based on a parameter. I assume that you already have a group of Structs or something to record the state of all your cells so this createCell() function could also be (re-)used to redraw cells during the game by looking up, via its ID, what settings it should use for the draw.

The last step would be the pixel effects so set the vertexColour per MO vertex like I mentioned, the value of a vertex's red channel might specify the amount of SomeTexture that you want to blend in, the value of a vertex's blue channel might represent transparency, green might be interpreted as a pulasting-ness factor etc. There's also 4 uv floats that can be set per vertex (and a bunch of other semantics you could hijack too) that could be used for that if you'd prefer to reserve vertex colour for actual colour of the squares.

And for the mouse picking you could do that a number of ways; get the world intersection location of the mouse cursor onclick and then find the closest hex cell.

Oh well, hope that helped, I enjoyed writing it :)
HTAPAWASO
Gnoblar
Posts: 16
Joined: Tue Jul 02, 2013 2:15 pm

Re: Improving Performance

Post by HTAPAWASO »

Thanks a bunch for the replies.

For now I have taken the simpler suggestion of batching each type of tile in a StaticGeometry. Performance has improved a lot, and while I still have to sort out the mouse picking, I doubt that will be difficult.
I really like the idea of having one ManualObject for the whole grid, it's certainly a much more elegant way of doing it. I have to think about it a bit more but I think I will ultimately attempt to implement it this way.
c6burns wrote:A batch operation is the rendering of a single set of vertices/indices with a single material. So in your modelling program, if you have 3 meshes with 3 materials that combine to make your character then it is going to take 3 batches to render. So some of the work of reducing batch count has to happen in your tools prior to export, by combining materials and even meshes if necessary.
I'm still confused about this. In Blender, my skeleton mesh is a single object. When I export it, the .mesh.xml file has one entry for <mesh> and one for <submesh>. There is one material file. Yet, each one is many batches. I don't understand why this is at all.

EDIT: Actually I've just determined that this is tied to sceneMgr->setShadowTechnique.
When set to SHADOWTYPE_STENCIL_ADDITIVE (What I had been using), each skeleton mesh uses 6 batches, while the other settings only use one.
The weird thing is that this happens regardless of whether an individual mesh's setCastShadows is true or false.
User avatar
areay
Bugbear
Posts: 819
Joined: Wed May 05, 2010 4:59 am
Location: Auckland, NZ
x 69

Re: Improving Performance

Post by areay »

HTAPAWASO wrote: I really like the idea of having one ManualObject for the whole grid, it's certainly a much more elegant way of doing it.
I look forward to the day when I finally release my RTS which will all be done in a single batch using the world's most complicated Ogre::ManualObject.
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: Improving Performance

Post by c6burns »

areay wrote:
HTAPAWASO wrote: I really like the idea of having one ManualObject for the whole grid, it's certainly a much more elegant way of doing it.
I look forward to the day when I finally release my RTS which will all be done in a single batch using the world's most complicated Ogre::ManualObject.
This post made my night haha :D
Post Reply