Rendering lots of little soldiers...500 how to keep speed up?

Started by
23 comments, last by johnnyBravo 19 years, 8 months ago
Hi, I'm making a strategy game where the terrain will just consist of rolling hills. So the terrain parts are fine, I can optimise that to the max. But drawing lots of 3D skeletal animated soldiers is a bit confusing to me. 500 or so onscreen. For my terrain I'm just grouping the same textured tiles and using one draw command to draw a hole bunch. But with lots of little men, I thought you would have to use matrices to move them around and animate etc, so I would be calling about 500 draw commands in between a bunch of matrix calculations. I believe this may be quite slow?, btw the men are quite tiny, so there isnt much detail per model, basically just body shaped parts, also im thinking of just loading .x files in and then just placing the models together eg arms,legs torsos to make a man and animate him. What are the ways of drawing lots of men and fast? thanks
Advertisement
You can group your soldiers into different animation states, e.g. you hav only say 5 different states and assign them to 100 soldiers each. This way you basically just process state transitions and bone setups for only 5 soldiers instead of 500 and then re-use these states by just translating the meshes to their output positions.

IIRC there was an article about that at gamasutra.com, I'm not quite sure, though.
I'm working on a similar project (in mine I'm using md2's) I am precalcing all the frames and a bunch of mid-frames as displists then just displaying, that way each soldier can have his own current anim offset (time from start) and still take advantage of pre-calcing. But if you wanted to use segments, you could put the segments in display lists and that would speed stuff up aswell. K.
500 animated objects is a lot. Also, with so many soldiers, you are getting into the realm of a particle system. The solution is to do more work on the CPU that will reduce the number of draws. Perhaps doing the transformations on the CPU and filling a vertex buffer with a soldier's pre-transformed vertexes is faster than the overhead of a draw. So for each soldier, apply its world matrix to the vertexes and copy them into a vertex buffer. Then do a single draw to draw all the soldiers.

If the soldiers are small and simple, you could precompute the animations. Then, for each soldier it is just a matter of using the precomputed mesh for the soldier's animation frame. That would save the time of animating all 500 soldiers every frame. You can also reduce the animation overhead by animating the soldiers at a lower frame rate (like 10 fps).
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
These guys used billboards:

how would you draw the animations pictures for billboards? looks hard


I thought maybe create the little soldiers out of a couple of triangles only, eg maybe 6-7 triangles for a leg, 8-10 triangles for the torso etc. Then test each of those triangles against the terrain triangles, so you could have the soldiers been blown to bits and their body parts could realistically bounce across the terrain.

Or would that just be way to slow with 500.

But I like the idea of sticking all the soldiers into a single vb with one draw call.

With premade animations, i want the terrain to have a bit of an effect on the soldiers so say they are walking or crawling up terrain, their guns or arms wouldnt cut through the landscape.
So im not sure about doing the premade animations


edit just realised what i just said is similar to s_p_oneil's idea, but anyway what you think?


[Edited by - johnnyBravo on August 19, 2004 8:05:25 AM]
Quote:Original post by johnnyBravo
how would you draw the animations pictures for billboards? looks hard


That's easy enough. You just render the men to the back buffer or some other render target, then copy the pixels into a texture buffer. The technique is called impostoring, and there are a number of articles out there that explain how to do it (a Google search on "impostor" and "billboard" should find them).

It is up to you whether you pre-render a fixed set of billboard textures or render them on the fly. Which you should choose depends on what you're doing and how you want it to look. Also depending on what you're doing, you may not want to use impostors when the camera gets within a certain distance.

EDIT: Oh yeah, you can also render directly to a texture if the card and API both support it. (It seems to be more widely supported in DirectX 9.0 than it is in OpenGL right now.)
Quote:Original post by johnnyBravo
I thought maybe create the little soldiers out of a couple of triangles only, eg maybe 6-7 triangles for a leg, 8-10 triangles for the torso etc. Then test each of those triangles against the terrain triangles, so you could have the soldiers been blown to bits and their body parts could realistically bounce across the terrain.

Or would that just be way to slow with 500.


It's not difficult to switch to a different animation when the little soldiers get blown up. You could either use particles for the flying body parts, or full 3D triangle meshes.

Quote:
With premade animations, i want the terrain to have a bit of an effect on the soldiers so say they are walking or crawling up terrain, their guns or arms wouldnt cut through the landscape.
So im not sure about doing the premade animations


This could be difficult, as you may have too many different pre-generated textures. They are small textures though, so it may not be that bad. You could easily create one large texture (i.e. 256x256 or 512x512), and fit many poses for one soldier inside of it.

Also keep in mind that it is possible to render into a texture one frame and use it for 10 frames, then update it and use it for 10 more frames. When rendering a squad moving together in formation, you may even be able to use one billboard rendered once for all the men in the squad for a few frames. Be careful though. If you use a dynamically-generated texture and don't reuse it often enough, it won't save you any time.
I wouldnt use skeletal animation for a RTS. It is just way too much overhead for 500 soldiers, instead by using a model with pre-calculated frames (MD2 like), you can save alot of speed.

I also agree on the drawing them with 1 call advice. Since each unit type will be using the same texture, you can buffer their vertices/normals/uv coordinates into 1 VB and draw them in 1 call.

As for their interaction with the terrain, you could rotate/orient them when they are walking up a hill. This will produce about the same result as orienting each bone for 500 soldiers would. Having each bone doing collission detection against the terrain is pretty expensive and would not really be better in a RTS where they are being viewed from so far away.
Ok, I guess I'll have to use premade animations etc.

I was thinking for billboarding idea, you could have one model drawn, then rotate, animate and set the camera on it,'take a picture of it at its current stance' then put that picture onto the billboard. to be drawn.

Then I would have only one model, and 6 vertices per soldier.

What do you think?

Would that be fast, like animating and rotating the single model 500 times and taking little snap shots of it(im not sure how fast the method is, ive got a tutorial somewhere on that) to be placed onto the billboards?

thanks

This topic is closed to new replies.

Advertisement