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

[Solved] Suggestions for reducing Draw Calls on this Control Panel object?

Discussion in 'General Graphics' started by Don-Whitaker, Mar 11, 2015.

  1. Don-Whitaker

    Don-Whitaker

    Joined:
    Feb 3, 2011
    Posts:
    39
    Currently working on a mobile (Gear VR) app. I'm looking for suggestions as to how I might reduce the total Draw Calls in this control panel object. Comes to 15 draw calls which doubles to 30 in VR mode.


    Currently the green 'console' object is one mesh and each rectangular button is a (quad) mesh with its own material and Collider. Colliders are used for raycasting - the player looks at each button with head tracking to select it. Each button needs to be able to change appearance and/or color independent of the others.

    Correct me if I'm wrong, but I don't think a Texture Atlas would help in this scenario since I need to be able to change each button image at will.

    Any ideas on how to make this more efficient?
     
  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
    theANMATOR2b likes this.
  3. Don-Whitaker

    Don-Whitaker

    Joined:
    Feb 3, 2011
    Posts:
    39
    Thanks for the suggestions mgear.

    Maybe I don't quite understand how texture atlas works. I could set up each quad with the proper UV to display the proper section of the Atlas, but how could I then switch images on each quad when needed? A new mesh object with different UV mapping?

    I think I will give the new Unity UI a try. Don't know why I didn't try that first, actually. I guess I decided no to use it because I was using the raycast setup for selecting each button, but I could still use it to display the images.
     
  4. Botanika

    Botanika

    Joined:
    Nov 2, 2013
    Posts:
    60
    I would bake UV data into vertex colors, and offset each button UV (vertex colors in this case) via script, to match the desired icon on a texture atlas. It should give 1 draw call in total I think.
     
  5. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    When using the the Unity UI, a sprite with the 'Button Script' component can easily swap out to another sprite upon rollover, press, etc... http://unity3d.com/learn/tutorials/modules/beginner/ui/ui-button

    If all your sprites are on the same atlas, that's the one draw call.

    If you bring your sprites in one at a time as separate images, make sure you set the packing tags such that they are all on the same atlas.

    Don't use the built in Unity sprites... Packing tags are f'kt-up.

    Highly recommend the excellent Texture Packer and free Texture Packer Importer available on the Asset Store
     
    theANMATOR2b likes this.
  6. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    It does not.

    Any UV offset in code, or manipulation of render materials via scripting increases the draw calls. You do, however, get Vertex colours for free, provided that you use a fixed function shader what will display vertex colors
     
  7. Don-Whitaker

    Don-Whitaker

    Joined:
    Feb 3, 2011
    Posts:
    39
    Thanks for the texture packing tips, this is something I haven't tried before. I guess I can't use the Unity Sprite Packer because I am in an Android project and don't have the Android pro license. I'll give that Texture Packer app a look-see.
     
  8. Botanika

    Botanika

    Joined:
    Nov 2, 2013
    Posts:
    60
    Yeah, I agree, any material change will create another material instance in runtime. what I meant, is instead of changing the UV offset in code, it's better to change the vertex colors values.
    I've already done something similar in this project, the whole environment is built with 4 materials (1 master material 90% of the meshes(with Lut textures, and uvs baked into vertex colors), 1 for decals, 1 for glass, and 1 for small props) and everything seems to batch properly.
     
  9. FuguFirecracker

    FuguFirecracker

    Joined:
    Sep 20, 2011
    Posts:
    419
    Indeed! :)
    Here's some code to do just that:
    [Attach to your quads]


    Code (CSharp):
    1. private Mesh _mesh;
    2. private Vector3[] _verts;
    3. private Color32[] _colors;
    4. private int _vertsLength;
    5.  
    6. private Color32 _onColor = new Color32(255, 195, 0, 255);
    7. private Color32 _offColor = new Color32(25, 32, 40, 255); // Whatever colors you want
    8.  
    9.   void Awake()
    10.       {
    11.          _mesh = GetComponent<MeshFilter>().mesh;
    12.          _verts = _mesh.vertices;
    13.          _vertsLength = _verts.Length;
    14.          _colors = new Color32[_vertsLength];
    15.       }
    16.    
    17.    
    18. void Start()
    19.       {
    20.          ChangeColor(_offColor);
    21.       }
    22.    
    23.  
    24.      public    void ChangeColor(Color32 color)
    25.       {
    26.          for (int i = 0; i < _vertsLength; i++)
    27.          {
    28.             _colors[i] = color;
    29.             _mesh.colors32 = _colors;
    30.          }
    31.       }
    Won't work with all shaders. Here's a simple one:

    Code (CSharp):
    1. Shader "VertexColor" {
    2.     Properties {
    3.        _MainTex ("Base (RGB)", 2D) = "white" {}
    4.     }
    5.     SubShader {
    6.        Pass {
    7.            Lighting On
    8.            ColorMaterial AmbientAndDiffuse
    9.            SetTexture [_MainTex] {
    10.               combine texture * primary DOUBLE
    11.            }
    12.        }
    13.     }
    14. }
    Still... Highly recommended to switch out to the Unity UI... Will handle sprite swaps and vert colors
     
    Last edited: Mar 12, 2015
    Botanika likes this.
  10. Don-Whitaker

    Don-Whitaker

    Joined:
    Feb 3, 2011
    Posts:
    39
    yeah, I like the sound of the UV offset and whatnot, but it is a little over my head. :)

    And - I already switched the images to use the Unity UI along with a sprite sheet. The 14 draw calls from the images are now 1 draw call! So I'm really saving 26 draw calls in VR mode since everything is doubled. :)

    Thanks so much for your help and suggestions everyone. I learned a lot this evening and my project is much more efficient. Also, that Texture Packer app is very quick and easy to use.
     
    Last edited: Mar 12, 2015
    FuguFirecracker and Botanika like this.