- Home /
Too much triangles and more doubts performance-related
Hello everyone.
I'm aiming for mobile platforms for my game. Mostly tablets but having also smartphone support would be nice, so I'm trying to keep things as efficient as possible. I'm trying to avoid instantiate as I've heard it hurts the performance on mobile phones. As I have no need for it, I already have all the models I need preloaded on the scene and position them as needed (no re-spawn nor infinite enemies in my game so no much trouble on that). I assume I'm doing this right aren't I? Or it's worse to save large scenes on my project rather than instantiating? (Btw even if using instantiating I'd do it on the loading screen, I don't think I'd need much instantiating in real time).
When talking on performance, the most important thing to think of is of course the 3d models. I have modelled some characters myself for my game, each of them is about 800 tris and 500 verts (on average). Is that too much geometry? Should I keep more simplified meshes? I also know that using a texture atlas works the best for keeping the cpu cost low, should I use texture atlases for all the characters? (Is there a plural for atlas?, nevermind xD) That surely sounds like more work, but if it helps I can do it.
Also, for some levels I'm planning on using the unity terrain feature, would that hurt performance on mobile devices? Is there a way to reduce the number of poligons for a terrain (By default is too high even for what I need). Will the multi-texturing feature on the unity terrain be a problem for a mobile device?.
Well, that covers all my doubts. Any other recomendation on improving the game performance is welcome as well.
Thank you very much
EDIT: Of course the point of using a texture atlas is to render all the characters using the same material.
Answer by Bovine · Jan 18, 2013 at 07:59 PM
iPad 2 and above have pretty strong GPUs. You can google for the varios triangle throughputs. We have animated models of around 1500 triangles. Not sure number of vertices and we handle 5 skinned meshes, I think around eighteen bones + around 15K geometry fine and could probably do more. The 3G S can just about manage the above as well and here I am talking about achieving 30 fps. We do take advantage of occlusion culling and have our own complex LOD system to ensure that we don't animate more than 5 skinned meshes at a time, swapping a skinned renderer for a simple idle pose model for all but the nearest 5 models in view.
Mobile GPUs are getting better, but alpha, multiple lights (we use one + lightmapped environments) and complex shaders, will kill GPU performance as the devices becomes fill rate limited for a given set of shaders or resolution.
Using any kind of per pixel lighting on underpowered GPUs, such as those in last generation iPod Touch, iPad 1 and iPhone 4 - those with higher density displays but older processors - can quickly fill limit the device.
We use per pixel lighting but will run at half the resolution (quarter the pixels) on these graphically underpowered processors. Note that we do use per-pixel lighting.
If you can use lightmaps and have no real-time lights or can fake them, then the shaders are much cheaper.
We have quite a high number of bones, the number of bones and the number of bones that can affect a vertex will have a compounded effect on framerate as you push the number of skinned animations - you might get away with a single skinned animation with 10K polys and 5000 vertices, but you won't be able to have many of those - possibly iPad 4 will manage a few more than an iPad 2.
Texture atlases are a big help as are shared materials. We have typically two for an entire environment at the very base and this is a good thing as with enemies, spell effects and the link we probably have dozens of materials and maybe a dozen textures in play at any one time (but our app is graphically quite intense).
I've never used the terrain system on mobile, but I know it works and is viable but cannot help there. Multi-texturing is entirely possible but texture look ups on mobile can be expensive, so it will depend on the number of different textures in play and how detailed the terrain is and the draw distance.
On mobile devices your heap will be small, so you need to avoid instantiate only because this can cause a stutter in the frame rate: instantiate as much as you can when your level loads; use prefab pools so you can recycle objects - typically we do this for spell FX and temporary geometry. Avoid new like the plague - new will allocate objects on the heap, and the more you new during your frame and the more often, the more the garbage collector will kick in. Similarly if you're instantiating and destroying objects I believe.
With audio you should avoid compressed audio types. We use uncompressed wav with same characteristics (mono, 8 bit, 22050hz), to avoid having to mix samples of different types and mono as the sounds are typically 3D sounds and so the stereo effect will be determined by the audio engine to give the notion of the sound's position.
You're already instantiating your enemies which is fine. Yes it will increase the size of the scene but I don't know by how much. There's no problem having some lightweight marker for an object and replacing it with an enemy when the scene loads using instantiate as you're doing this when the scene loads rather than every frame - instantiate is fine onlevelwasloaded.
Sorry but I have not tried Android devices as yet, so I cannot speak for these but there are similarly powerful GPUs in android devices, some more, some less powerful. We'll get to android devices just as soon as we have released for iOS, or earlier if a quick port to OUYA looks promising :D
Wow, this really helped a lot. I'll try to do all you're telling me in order to reduce performance issues.
And I didn't even know I should avoid "new" as well. Does that apply to small classes or structs like the Vector3 or any small data containers i need to manage in runtime? What do you recommend to use ins$$anonymous$$d?
I'll take note on all that to continue my project, thank you very much ^^
Avoid new full stop really, but especially so for reference types as you will cause garbage collection to kick in with these. I cannot comment on the workings of value types (like structs), other than to say they are allocated on the stack.
If you could accept me answer, that'd be appreciated.
Oh yes, of course. I totally forgot about accepting your answer. $$anonymous$$y bad.
I'll check those links as well
So to go a little more further on that "new" question, i want to ask:
Let's say my game consists in a map (a grid, to be more specific), I need to have some kind of data structure to save the information on all the map, so I create a map class, which holds an array (a matrix actually) of tiles, each tile needs to be an instance of the "tile" class. I don't see any good approach to do this without even using classes nor the new keyword :S How am I supposed to even store the information for the map? I've found some valuable info in those links but no real answer to this, and, as you can see, it's not possible for me to completely avoid the "new" keyword, so should I stay away from mobile market just because my game runs on a grid? I think there are apps on the android market (or the appstore) way more costly than this. This is what I don't see really clear :S
That would make much more sense if you were only telling me to avoid new (or instantiating, which is preety much the same as I've been able to read) during real time gameplay, and save all my instantiating for the loading time, I understand that and I was planning to do so