Lotus has a really great post about aircraft performance in FSX. I highly reccomend reading the whole post. It's a bit technical, but does put into practical terms a lot of the ideas about how to create performant aircraft (especially for multiplayer). Draw calls are not always the single performance killer and reducing draw calls is not a silver bullet for creating objects that perform well in the engine. I talk a little about this in my "When is a draw call not a draw call" post. Lotus does a really great job of showing practical numbers from existing addon aircraft.
The reason for some of his findings has to do with what is being updated and sent to the GPU from the CPU. If each of the draw calls in an aircraft is close to 65,000 vertices, then each draw call is sending almost an entirely full vertex buffer update to the card every frame. While it is still only a single draw call, it is a huge amount of data being sent across the pipe. So 35 draw calls with 1000 vertices each does not equal 35 draw calls with 60,000 vertices each. And if you are using poor UV and smoothing techniques, then it is very easy to get a 25,000 polygon model close to that limit for each draw call.
Another comparison I'd love to see is the animation hierarchy in the aircraft. An aircraft can be skinned and have 15 draw calls, but have 10 parallel animation hierarchies that are each 20 levels deep. The amount of data needing to be updated during each frame becomes gigantic (something on the order of 2100 matrix transforms per frame). If that same aircraft were animated with a flat hierarchy (not always easy or even possible to do) it would have about 200 transform matrix updates each frame.
All in all, it's a great post and a very informative read. Excellent work, Lotus!
Hey Torgo, I'm glad you liked the post. I wasn't sure if you'd seen it or would approve, but no one had done that kind of testing before and your performance posts made me really curious about it, so I had to take a look. :)
There's probably a bit of associated karma involved but the draw calls are starting to catch up with me in my L-39's VC, in obscene fashion haha. A dual seat plane with two completely 3D gauge cockpits (50+ gauges), and just about every control animated, can really chew through the draws fast. Your comment about the hierarchy is enlightening too. I need to take a look at that.
It's good to see someone in the community doing this kind of research! We're doing quite a bit right now to clean up our rendering engine. I think you'll enjoy the results.
Unfortunately for SP2 we weren't able to batch up objects with Mouse Rects on them, which is probably what's killing your VC. We do auto-skinning on animated parts, but we didn't get time to figure out the batching on Mouse Rects (because the radius would be the whole batched group of switches and knobs and not the individual part). We're definitely looking at that problem as some of the 747's interiors can be a real killer, with hundreds of draw calls for the interior 3d cockpit.
I'm very glad to hear about the rendering improvements for the next version, great news, can't wait!
Your mouserects comment is spot on too I think as I have loads of them, probably around 100-150 with more needed every day.
Which leads me to a question if I may (because if you don't know the answer to this then I doubt anyone else in the world does haha):
Which is cheaper? Using an animated part, lever or handle etc, as its own mouserect, or making a static box with a small transparent texture that encapsulates the lever's general area and using that as the control mouserect instead? It would mean more draw calls I think doing it this way, but it's almost impossible to test for the performance impact of mouserects from my end.
I do it this way for some things, where overlapping geometry is necessary, and messes up line of sight, but I'd love to know your thoughts on it.
Hmmmmm. Good question. Just off the top of my head, it's probably about the same (unless we don't autoskin in the VC, which I think we do).
In the first case, each animated part will get its own draw call and there will be no autoskinning. If the materials are very similar, or identical, then it should draw very quickly with very little material switches in between draw calls.
In the second case, each of the static boxes will be a new draw call, but there will be nothing to draw. There will be extra draw calls because the animated, auto-skinned switches and knobs will draw in batches based on material settings.
I'll try to get a more thorough answer to this.
Awesome, thanks for looking into it. You're no doubt right, it's probably about the same hit, but when you have hundreds and hundreds of mouserects, some of which are on high poly parts, who knows. :)
Great post, explained really well and I could really understand. Thank you.