Game Development Community

Reducing draw calls / increasing performance

by Aleksander Elvemo · in Torque 3D Professional · 03/12/2010 (7:55 am) · 34 replies

Hi!

I have some questions wich are puzzling me. I've tried to search and got many answers, but some the questions remains unanswered.

In my game I try to push in as many ai-characters as possible (strategygame). So without any form for AI-functions running/thinking, I have just run my tests with 90 simple boxed shaped humanoids. Each of these has a polycount of 120. Every humanoid also has a simple 1024x1024 basic texture, which is almost a singlecolor.

Now, I have made a function which spawns 90 of these in a mission which is the standard blank emptyRoom.mis that loads when you press F11 when you're not currently in a mission.

Readings from the emptyRoom without any models:
FPS: 160
Draw Calls: 25
PolyCount: <5000

After adding 90 models with 120 poly, that should be total 10800 polys give the readings;
FPS: 35
Draw Calls: <4000
PolyCount: 50 000

Now some things are a bit wierd I feel here. First of all, the low box humanoid is a LOD version of a higher poly model, but I'm hundred percent sure that the 90 models on screen indeed is that low poly version, and the number itself, 120, comes from the shape editor which I found by selecting that particular LOD version.

Should I be expecting: <5000 (level itself) + 10800 polys, or should it actually be around 50 000? I was expecting a 1/5 of the values im getting. Also I read a comment that draw calls never should go above 2-3000, and im at 4000+! Are there any clues to why the performance is so bad?

To validate my results I will confirm at once that I have tested in fullscreen mode, with the camera standing completely still, only using a single command for spawning 90 models, and using the function metrics(fps) and metrics(gfx).

Hope anyone could enlighten me! Thanks for any replies in advance :)

EDIT:
I found out the model does not use one texture, but 3 at 512x512
Also, could mesh hiding be a part of the problem? Atm the models are hiding about 10 meshes (boxes mostly)
The whole model is also 11 seperate meshes, so that every part can be mesh hided, can this be the reason performance falls?
Page«First 1 2 Next»
#21
04/03/2010 (3:46 am)
Yeah, Atlas textures were my first thought (forgot the name of the technique, though, so I couldn't find any information on the implementation), but we don't really know how to handle the code that assembles/gets the needed UV space.

There aren't any resources on this, are there? I've searched around, but haven't been able to find anything.
#22
04/03/2010 (7:41 am)
Just to point out that combining a few non-tiling object textures akin to Manoel's diagram (8x512 == 2x1024) I've reduced my drawcalls for my level by between 50-150 depending on small-big scene with a 7fps boost, and think that a bit of mesh reorganizing (originally set up for lots of small meshes with 512 lightmaps - so turn them into 4x512=1024) will reduce drawcalls further.

"Atlas" texture = MegaTexture?

Won't you still have to watch the overall size of your texture and how much texture memory it uses?

It's all a trade-off in the end ...
#23
04/03/2010 (9:53 am)
A texture atlas would allow us to set the clothing and face textures dynamically, while the mega texture approach necessitates the use of one texture for every combination possible, which would be fine for predefined NPC characters, but not for player characters who have a large variety of combinations to choose from.

@Steve Check out this wikipedia article for some more information; http://en.wikipedia.org/wiki/Texture_atlas
There's a link to both the original white paper from NVidia, as well as an interesting article by Gamasutra. Both are rather ancient though, so there might be an alternative, more modern solution to my problem.

EDIT: Noticed that what Manuel was saying is almost the opposite of my original thoughts. I hadn't even considered somehow combining the textures at runtime. How would you do this, and wouldn't it have the same issues with memory use as making every combination manually (given that multiple combinations are shown on screen simultaneously)?
#24
04/03/2010 (2:29 pm)
@Steve i'm emailing tena to advise them that there may be a market for a Tena Gents product line... :)

But back on topic, could somebodt point me to the section of the code where the metrics are counted or even better if individual metrics are counted somewhere easily accessable, it would be quite interesting to select an object and see directly how much memory, drawcalls etc etc that object generates, it would help enormously in choosing what to optimise and perhaps how
#25
04/04/2010 (12:27 pm)
@Christian: yeah, memory can be a problem if you have tons of characters and many of them use a common cloth piece.

The most robust solution would be packing the cloth pieces into a huge virtual texture, and use shader constants so each character shader knows the UV offset to find the cloth pieces it needs. However it takes some work to implement it in an elegant way. It would also be tricky to get DXT compression going on.
#26
04/04/2010 (12:36 pm)
Yeah, that's what I first thought you meant when you mentioned atlas textures. As I mentioned, I have no clue how to implement this, so I'm just hoping someone will make a resource for a similar purpose. I'm just keeping a number of preset texture combinations for now, but hopefully there'll be a solution for including some more customization later.
#27
04/04/2010 (1:07 pm)
Take a look at the parameters: cellIndex, cellLayout, cellSize, and bumpAtlas on Material.
#28
04/04/2010 (3:01 pm)
@Pat: whoa! However, it's not quite the solution for drawing a character in a single call, since each clothing piece would need a different material.

@Christian: you can build an atlas using render-to-texture, drawing each texture to its assigned area. You can even save it to a file by calling copyToBitmap() on the render target texture (TerrainBlock::_updateBaseTexture() is a good example: it builds the blended terrain texture then saves it to a DXT1 compressed DDS file).
#29
04/10/2010 (5:32 pm)
Yes, that could indeed work, if that functions the way I think it does. Part two of the problem is that we use mesh-hiding for things like armour and hats, which increases the drawcalls quite substantially when visible. Are there any techniques to remedy this?
#30
04/13/2010 (1:01 am)
That's interesting, is this drawcall behavior in all 3D engines? or is it a quirk that belongs to T3D?

Sounds like instead of doing mesh hiding, one would have to somehow write a piece of code that "merge" on the fly individual models & textures before sending them to the engine...
#31
04/13/2010 (8:21 am)
Yeah, that was my thought as well. I wonder how this is usually handled by games with a great variety in customization, like MMOs and certain RPGs....
#32
04/13/2010 (11:18 am)
@Christian & Kyrah

This isn't a problem unique to Torque... even people using UDK have issues with these systems.

The truth is if you want a good system for switching out "parts" of a model you need to spend time developing one.

Mesh hiding and mounting might be good solutions depending on your game and your needs.

A possible better solution would combine meshes into one single mesh quickly on demand... essentially building a new TSShape on the fly. I'm sure some of major RPGs and MMOs take that sort of route specifically to reduce draw calls, but at the cost of more VB space. It just takes some effort to implement... but its totally doable.
#33
04/13/2010 (3:39 pm)
I'm just wondering how other games/engines work around this problem.
#34
06/15/2014 (9:47 am)
Reviving an old thread here. Bloodknight brought up a question/point that I currently have when he said "it would be quite interesting to select an object and see directly how much memory, drawcalls etc etc that object generates, it would help enormously in choosing what to optimize and perhaps how"

Is there any way to do this these days?
Page«First 1 2 Next»