Search Unity

Static batching use a ton of memory?

Discussion in 'iOS and tvOS' started by techmage, Sep 1, 2011.

  1. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    So I was going to post the following:

    But then I realized my 70+ mb of memory usage was coming from the use of static batching, which I was enabling by having to check all my objects as 'static' in order to bake them. So I am wondering, why does static batching use so much memory??? It clearly seems unusable to me if you plan on putting alot of vertices into unity. Is there some way you could get benefit out of statically batching some objects, but not others?
     
  2. bdev

    bdev

    Joined:
    Jan 4, 2011
    Posts:
    656
    I have to think the reason it takes so much memory is because of the amount of memory needed to build the mesh. I don't know how the internals work, maybe someone from unity can clear that up. But if it is actually combining the meshes at runtime, it basically allocates a array for each vertex element per vertex per mesh then has to move all that into a fixed sized array the size of all the vertices combined. So if you've got 500,000 vertices each with a normal, uv, position, and tangent that comes out to be 24,000,000 bytes ( or 6,000,000 floats ) for vertex data alone. and then having multiple of those as far as the scripting interface is concerned to combine those meshes you would need to allocate that data that many times but in a fixed sized array which cna be alot to ask for on ios and often what leads to crashes on devices which have been on for a long time and have memory footprints all over.

    And when you static batch, all mesh renderers using the same material are combined into one mesh.

    Static batching is generally a good thing, but i think the problem is your massive vertex count mesh. I do not think its doable, especially if were talking about 2nd gen hardware but its i think over the line of pushing it on even the ipad.
     
  3. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    I would like to know what static batching does internally. For the amount of RAM it takes up it seems like it would have to make a duplicate of all your meshes combined in every possible configuration they could be combined in.... for 6 mb of mesh data it's literally adding 70+ mb, I don't really know how much it adds because it crashes...
     
  4. ReJ

    ReJ

    Unity Technologies

    Joined:
    Nov 1, 2008
    Posts:
    378
    How many instances of that "huge" mesh do you have in your scene?
    Basically static batching has to create a copy of geometry for each instance. For instance if you have in your scene 10x instances of 500Kverts mesh, you will end up with 5MVerts in memory due to how static batching works. Unite will NOT render all of them of course, but they need to be in memory.

    This is described in http://unity3d.com/support/documentation/Manual/iphone-DrawCall-Batching.html

    NOTE: If you have a single instance and you experience problem like that - please, submit your test application together with bug report.
     
  5. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    So what static batching does is it turns instances into their own separate poly object? Doesn't that kill any performance gain that can be had by instancing geometry? Is it better to not make instances static for that reason?
     
  6. ReJ

    ReJ

    Unity Technologies

    Joined:
    Nov 1, 2008
    Posts:
    378
    There is NO instancing on iOS or Android (OpenGL ES doesn't support it).
     
  7. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    What about on PC then?
     
  8. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    I am bumping this thread again because I still am a little confused on what static batching is doing internally. I'm running into areas where I feel I need to know more about static batching in order to use it fully.

    I understand that whatever object you check static batching on, at runtime, Unity will combine all those objects. But how is that superior to just combining the geometry in a modelling application? It seems to me that static batching is doing the same thing as just combining all your meshes in a 3D app. Is that true? Or is static batching doing something more?
     
  9. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Not at all, or frustum culling wouldn't exist.
     
  10. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    So static batching in some way combines all of the geometry, but does it in such a way that frustum culling still works?

    I don't understand how is that possible? Does it take all your mesh data and then read it into some special data structure that it can check against frustum culling and then only send the vertices it sees? Is it something fancy like that or is there something simpler going on?
     
  11. DanTreble

    DanTreble

    Joined:
    Aug 31, 2010
    Posts:
    590
    The mesh is in 2 parts. One huge buffer of vertices (positions,normals,uv1,uv2 etc...) and a index buffer. The vertices get uploaded to the GPU as a VBO and there they stay. However the index buffer is created every frame and uploaded to the GPU. The dynamic index buffer allows smaller parts of the big mesh to be turned on and off. I'm told that updating the index buffer is really quick and I can believe it :)

    So you are still paying for object level culling, even when you static batch. We got a real win from baking course occlusion data. Means it has less objects to frustum cull.
     
  12. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    I see.

    So how can I caclulate how much memory static batching will take up?

    Do I just turn all my instances into their own meshes and then double that amount?
     
  13. DanTreble

    DanTreble

    Joined:
    Aug 31, 2010
    Posts:
    590
    This line in the editor log, after a build

    Well, that was at least what we assumed it was
     
  14. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    I have a scene that has about 300,000 vertices in it. There is no instances, not a single instance anywhere.

    With static batching off the app profiles at using 104mb of RAM. With static batching on it profile at using 140 mb of RAM.

    I am a little confused on how to figure out what exactly it's occurring.

    Here are the statistics from my build with static batching on:
    Textures 32.9 mb 59.6%
    Meshes 217.5 kb 0.4%
    Animations 0.0 kb 0.0%
    Sounds 0.0 kb 0.0%
    Shaders 65.5 kb 0.1%
    Other Assets 5.2 kb 0.0%
    Levels 18.0 mb 32.7%
    Scripts 126.3 kb 0.2%
    Included DLLs 3.8 mb 6.9%
    File headers 19.4 kb 0.0%
    Complete size 55.1 mb 100.0%


    Here is my level compile stats with static batching off:
    Textures 32.9 mb 76.5%
    Meshes 6.0 mb 14.0%
    Animations 0.0 kb 0.0%
    Sounds 0.0 kb 0.0%
    Shaders 65.5 kb 0.1%
    Other Assets 5.2 kb 0.0%
    Levels 49.6 kb 0.1%
    Scripts 126.3 kb 0.3%
    Included DLLs 3.8 mb 8.9%
    File headers 19.5 kb 0.0%
    Complete size 43.0 mb 100.0%

    So it seems to take my 6 mb of meshes, and do something internally to triple there memory size, and then store 18mb in 'levels', and reduce 'meshes' to a measly 217kb.

    What is it doing to triple the memory size? I'd really like to know that.

    And if the log is reporting that it is going from 6 mb of memory to 18 mb of memory. Then why is it that on the actual device, when profiling the app, its saying its going from 104 mb of memory to 140 mb in actual memory usage?

    Is the level data stored in like a compressed format of some sort, and then it is decompressed at runtime?

    I really wish Unity had far more in-depth technical documentation on it's internal workings that would explain things like this.
     
    Last edited: Apr 5, 2012
  15. DanTreble

    DanTreble

    Joined:
    Aug 31, 2010
    Posts:
    590
    Interesting. I don't think the Level section is stored compressed. I'm not sure what else it includes, maybe static collision?

    Something I've not worked out is how unity decides the vertex format in the static mesh. For instance in your 'dynamic' mesh you might have (pos,normal,uv) the static mesh that unity creates could end up with (pos,normal,tangent,uv,uv2,color) to accommodate the worst case.

    I'm sorry, I know that doesn't really solve your mystery. I'd also love to know the 3x disparity.
     
  16. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    Hey, I am bumping this old thread again the hopes that someone, or maybe even a unity engineer would be willing to share some more information about static batching.

    I would really like to know what static batching is doing internally and how to roughly calculate how much a RAM a certain scene will use if statically batched.
     
  17. sama-van

    sama-van

    Joined:
    Jun 2, 2009
    Posts:
    1,734
    Batching process is affected by vertex count on your object and the way Uvs are a made on your object + edge smoothing (from vertex).

    I made a few test 3 years ago with a single cube into Unity, different Uvs and smooth group to check the vertex count in the engine.

    - http://a.samavan.com/Test_TriangleStrip_Cube_A001.jpg


    To resume, with a single cube, depending of how it is made, you can get many result concerning memory resource.
    It looks a cube, but striping is the root of batching process I guess?


    Also batching is a method almost running on each frame then need extra memory to be done as well.
    Becareful with huge batching on iOS =___=....
     
    Last edited: Feb 11, 2013