Search Unity

A few big textures or a lot of small ones?

Discussion in 'General Discussion' started by swyrazik, Jun 28, 2013.

  1. swyrazik

    swyrazik

    Joined:
    Apr 21, 2013
    Posts:
    50
    I've been working on a 2D game lately, which makes use of quad meshes with textures, and a question came to my mind. The game is tile-based so the map is basically composed of many equally sized tiles (quads).

    So I was wondering (concerning the map) whether it's better to have one (or a few) big quad with a big texture of the map on it or many small quads having as textures the composing parts of the map? Given that the textures are all placed in a texture atlas, so the draw calls will eventually be batched.
    My thoughts are that a big quad would be better performance-wise because it's only one object, while the many quads would be better because they would make the map easier to edit/manage.
     
  2. the_motionblur

    the_motionblur

    Joined:
    Mar 4, 2008
    Posts:
    1,736
    Depends on a few factors.

    Basically you should first decide how much of the texture can be seen at one time on the screen. For every object that uses a part of that texture - no matter how small - the whole thing has to be loaded into the memory of your system. So if you're going to have only - say maybe a third of the texture visible in a lot of comstellations of geometry on your level then you might think about splitting it up.

    The most performat solution would be to have one texture atlas with one corresponding material spread across your level. Your level should use or even better: reuse a lot of information from the texture at a time shown on screen. Also your level should then be split into chunks of geometry that can be culled easily for best performance. That approach is your safe bet on any mobile plattform - and in that case you might also want to think about axing all pixelshader materials if you want to support a lot of older hardware.

    If you're aiming for current generation desktop systems the this is not so much of an issue. in that case I'd ted to split up texture atlases into chunks of logically placed objects that usually are bunched together in a map. So maybe if you want to create a warehouse with loads of metal crates and barrels and metal shelves - that might be a good idea to bunch together in one atlas as the resulting material will probably be shared across all these objects: they're all metal and will show up together. Be aware that of course what I wrote eralier still applies: should you later on want to place only one barrel somewhere else then the whole shabang of crates and shelf texture information will have to be loaded into your GPU RAM again and be wasted.

    Splitting up into many materials and textures on the other hand increases drawcalls and the amount of access to reload the textures into your graphics card. So really there is no exact solution to this. It all depends on your project and desired fexibility later on.
     
  3. swyrazik

    swyrazik

    Joined:
    Apr 21, 2013
    Posts:
    50
    Thanks for the detailed answer. I have understood everything that has to do with textures. However, the geometry part is still not clear. You said it's better to have many small geometries for better culling. But doesn't having, let's say, 10x10 = 100 quads visible on the screen mean worse performance than having one big quad with the size of the 100 quads? Or only the GPU rendering really matters for performance? Do GameObjects along with their MeshFilters need a noticeable amount of processing, if we neglect their MeshRenderers?
     
  4. the_motionblur

    the_motionblur

    Joined:
    Mar 4, 2008
    Posts:
    1,736
    What I mean is that you should avoid having one mesh that is only one object for your whole level. Every mesh that is on camera has to be loaded completely into the memory. That means that if you don't break up your meh into at least a few smaller parts your whole level that is using one texture has to be rendered and remain in memory, entirely.

    There are a few very helpful topics about optimization and how much to combine and split apart in the documentation.
    It's explained very in depth, there :)
     
  5. swyrazik

    swyrazik

    Joined:
    Apr 21, 2013
    Posts:
    50
    Thanks again. I have gone through the documentation and I found what I was looking for:
    So having one big quad (4 vertices) is better than having 100 quads (400 vertices), but that would mean painting my map in big textures rather than small parts of it, although it would take more time to paint or repaint them.
    I guess I'll stick with lots of small quads (my current implementation), until I see that the performance drops due to the high number of vertices - which I don't think is something I will reach.
     
  6. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    1,512
    Nope, you are missing the subtlety here, its saying that one mesh of 100 quads is going to be more efficient than 100 meshes of a single quad. Its all about reducing the number of drawcalls, that is how many times the cpu has to tell the gpu to draw something each frame as that has an intrinsic overhead involved.

    Although your single big quad may be faster in terms of vertex processing than 400 quads as a single mesh, the amount of time difference is going to be almost negligible, making it an irrelevant comparison. Meaning you need to factor in that in terms of polygon counts 400 vertices is nothing these days, optimal throughput on a gpu, even mobile is likely to be of mesh calls with 1000's of polygons/vertices. Exact numbers are going to depend on underlying hardware, but when you get down to it, its all about 'throughput' making sure the hardware stays busy, whilst avoiding unnecessary calls from cpu to gpu (i.e drawcalls).



    Yep, this sounds best, especially if you are already using texture atlases and have static/dynamic batching. There may be a point where dynamic batching becomes a bottleneck, but then if you were going to be able to make a single big quad instead of 100 smaller ones, it was going to be static anyway.

    Static batching or use of te combineMesh script in unity helps ensure that although you have hundreds of little quads, they are all 'batched' together into a single mesh and thus a single drawcall, instead of hundreds of drawcalls. Of course for batching to work they need to use the same material and texture, hence needing a texture atlas in this case.

    However this all depends upon how you are dealing with you lots of small quads. Its all very well having each as a gameObject and letting Unity take care of static or dynamic batching, but that's not taking into account additional aspects such as do you have monobehaviours on each gameObject? If you did then that could easily become problematic as the world grows. Though I doubt having 400 Updates() running every frame would be an issue, it is something that can easily get out of hand, and end up burning cpu processing.

    If this is the situation then it is likely to be far better for you to take over dealing with the quads and gamelogic yourself and create a master class which can build the quads, deal with any game logic, find the quad a screen point or game entity is over etc. Instead of putting the same code on every single little quad.

    Overall, though i'd probably start from creating a master 'map' class, you shouldn't need to bother changing your current method, not unless or until you feel its counter-productive to performance. The advantage being that should you need to implement a master map class, you'll be in a better position to know exactly what it needs by then.
     
    Last edited: Jun 30, 2013
  7. swyrazik

    swyrazik

    Joined:
    Apr 21, 2013
    Posts:
    50
    Thanks a lot, this couldn't be more clear.
    I knew that probably the number of quads I have would be negligible, but I like to know exactly what I'm doing so that I can more easily locate the source of possible problems that might appear. If I face any performance problems, the master class you suggested will be my first approach.