Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Why Does Reducing Materials Increase Batches?

Discussion in 'General Graphics' started by John-B, Feb 10, 2018.

  1. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    I had 9 objects in my scene, all different, but they shared the same 10-12 materials. I thought it would improve performance if I combined the textures into an atlas, so now those 10 objects all use just one material each, the same material for all 9. Not only did this not improve anything, but it seems to have made it worse.

    Each object with 10-12 separate materials: Batches: 259, SetPass Calls: 73, FPS: 120
    Each object with 1 material: Batches: 281, SetPass Calls: 66, FPS: 120

    There are other objects in the scene, that's why the numbers are so high and why I'm trying to optimize things. The objects are not static, they can move around. Static and dynamic batching is on (turning dynamic off makes the batch count go way up). Shouldn't both batches and set pass calls go down?

    Getting rid of the normal map on that one material (standard shader) reduced batches to 251, and increased the frame rate to 135 FPS, same set pass calls. Previously, some of the textures had normal maps and some didn't. Why would adding a normal map to one texture increase batches by so much?
     
    Last edited: Feb 10, 2018
  2. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    I can't answer any of these questions. However a thought; Do any of the 9 objects with original materials have transparency/alpha at all? Usually it's suggested to separate transparent and opaque materials for optimization purposes.
    Hope you solve. Rendering seems to be very,, 'situational'.
     
  3. McDev02

    McDev02

    Joined:
    Nov 22, 2010
    Posts:
    664
    Are you sure that the other objects do not affect this? Just slight dfferences in the camera angle can cause different batches. Shadows affect batches as well. Also if you had those materials on other objects in the scene this can affect batching as well.
    Normal maps do not affect batches. You should isolate these objects and move them into an empty scene. Then you can see the difference.
     
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,281
  5. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    Thanks for the info.

    Everything is the same in my comparisons, I'm looking at the opening scene which has the same camera settings, same objects in view, etc. No shadows, no anti-aliasing. I click Run and look at the Stats panel. I'm trying to isolate variables one at a time in the actual scene because I don't really understand how/if using textures atlases is a good thing (see my question below). But it is true that adding/deleting a normal map from the Standard Shader for that one material (that is not used on anything else in the scene) did make a difference in batches. Switching from Standard to Mobile Diffuse further reduced batches, Mobile Diffuse with normal increased batches. Adding shadows increases everything, a lot.

    After playing around with this some more, I don't think I really understand how textures atlases work to reduce batches/set pass calls, and if they're always a good thing.

    For example, let's say I have one object in my scene and it uses 10 textures/materials. That's bad. If I combine those textures into an atlas, then my single object now uses only one material. That's good, batches are reduced (and set pass calls?). What I'm not clear on is how well that scales.

    Now let's say I have 50 different, unique objects in the scene, each of which uses several materials. Most materials are shared, so the 50 objects use a total of 40 different materials. If I combine the textures for each of the 50 objects into atlases, each object would then use only one material, but there would now be a total of 50 materials in the scene. I don't know if that's good or bad. Total number of materials goes up with the atlases, but the number of materials per object goes down. Since I could potentially have a number of different objects in my scene at the same time, I'm wondering if using texture atlases (increasing the total number of materials) might actually slow performance. To complicate things further, the user adds objects to the scene, so there could be just a few or there could be a lot.
     
    Last edited: Feb 15, 2018
  6. BrandyStarbrite

    BrandyStarbrite

    Joined:
    Aug 4, 2013
    Posts:
    2,074
    Okay:
    First off, textures and material/shader's, are both, two completely different things.

    Textures: are the cover/skin surface for an object.
    Used, to plaster onto an object(s) surface, to make it/them, look like something
    that exists in real life. Eg. A photo of rocky ground, sand, a wooden floor etc.

    Material/Shaders: determine how the textures, would look.
    And by playing around, with the materials settings, can make a soil,
    or wood texture, look strangely glassy looking, soft, or look like fake plastic.

    Okay, question. In your first post, you mentioned a normal map.
    Did you turn the normal map, into an atlas too?
     
    Last edited: Feb 15, 2018
    PutridEx likes this.
  7. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    I understand the difference between textures and materials. Now that you mention it, I see a couple of places where I used texture when I meant material. Those are now corrected.

    And yes, I generated a new normal map to match the texture atlas. I had to, since you can only have one normal map per material.

    Update: I just tried enabling GPU Instancing on a few different materials that are used on several objects in the scene. Turning it on more than doubled the number of batches, and reduced Saved by Batching by a third, no change in SetPass Calls. The debugger says: Rendering different meshes or sub meshes with GPU instancing. If I turn it off, it tells me I don't have GPU instancing enabled. So it looks like enabling GPU Instancing is bad in this case, which sounds like the opposite of what should be happening.
     
    Last edited: Feb 16, 2018
    BrandyStarbrite likes this.
  8. McDev02

    McDev02

    Joined:
    Nov 22, 2010
    Posts:
    664
    My experience is that dynamic batching causes framerate to go down, at least for higher counts of objects. This might be individual but I had this experience in numerous scenarios. Maybe the issue is that it tries to batch everything but if we could select which objects should we batch and which not might help to improve things.

    So if you can focus on StaticBatching. Also dynamic batching makes sens for small objects. Objects with just 300 to 900 Vertices don't even batch. If you deal with runtime generated content which is static then you can try CombineMeshes.
     
  9. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    After converting all the individual textures to atlases, so that (almost) all the objects that appear in my opening scene now have only one material each, I've reduced the Batches/SetPass Calls from 259/73 to 186/36. That's a pretty decent improvement, and I still have a few unnecessary materials that I can get rid of. But I'm still not sure if this improvement will scale up when there are lots more objects in the scene. That's really my main question, is using texture atlases always good for performance.

    I'm also a little surprised that my canvas alone accounts for 19 Batches and 5 SetPass Calls. I thought Unity is supposed to combine and batch UI graphics. I used to use EZGUI, and it combined textures into atlases, so the entire interface was usually just 1 or 2 draw calls. With the Unity UI, it looks like every interface object (text, image) is its own batch.
     
  10. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
    If you use most of the object that are inside that atlas then yes, if you have a lot of atlasses and only use one of the objects that have the texture on it, its a waste in video memory but not a problem otherwise.
    You have to combine the sprites into sprite assets. Set a Packing Tag inside the sprite importer dialog.
    You can check how good its working in the sprite packer window.
    Then unity should combine any sprites together that use the same ui material (normally everyting is the same material in the canvas)
    Also using canvas groups and different canvases will cause additional draw calls.
     
  11. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    I don't know why I thought Unity did it automatically, but combining the UI images into an atlas reduced batches, though not as much as I'd hoped. It looks like all the images are being combined into one batch, but it also looks like each text item is its own batch. Apparently, text is the enemy of Unity's UI.

    I also noticed that most of the objects that I reduced to 1 or 2 materials are now 1 or 2 batches, but not all of them. Some either had too many or too few vertices for Unity to batch them (not sure which). I found some code that combines meshes (the code in the Unity Script Guide doesn't work), and that did the trick, bringing them down to a single batch each.

    So from my original Batches/SetPass Calls of 259/73, I'm now down to 56/32. I'm pretty happy about that.

    One thing I forgot about is that a couple of objects have moving parts, which do not move when combined into a single mesh. I'm going to have to exclude those from the combined meshes, which will probably make my numbers go up a bit. Also, a few objects were invisible (MeshRenderer disabled), and they have to be excluded.
     
    Last edited: Feb 20, 2018
  12. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,967
    Sounds like your not using text mesh pro.
     
  13. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    No. What is it, and should I be using it?

    Ah, I see. I'll have to take a look. It's not obvious if it can be used with button text.
     
    Last edited: Mar 3, 2018
    MadeFromPolygons likes this.
  14. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,967
    Its far far more performance efficient and in general easier to use, more customization options text solution that is viewable at all resolutions :) and its now free!

    Definately take a look, soon itll replace built in text.

    EDIT: yes you can use it on buttons or for any text you need. UI or otherwise
     
  15. Fressno

    Fressno

    Joined:
    Mar 31, 2015
    Posts:
    185

    Hey. I know this is an "old" post, but im having the same issues today. You mentioned a script that was not from the Unity script guide. What was the script that helped you? im very curious as that might make my day =)
    Hope to hear from you /Fress
     
  16. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    What I have is not very generic, and I don't know where I found the original code. I can send you what I have in a private conversation, if you like.
     
  17. Fressno

    Fressno

    Joined:
    Mar 31, 2015
    Posts:
    185
    yes please. anything will be of help.
    thanx!
     
  18. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,259
    Sent. HTH.
     
    Fressno likes this.