.
  • Content Creator Blog - Draw Calls and Materials

    Last week we talked about how Level of Detail (LOD) is being updated to allow content creators to get the most efficiency out of the engine. While adding LODs will reduce the polygon count of your scene, and there are other factors that impact performance. So this week we'll review how to optimise your content to avoid excessive Draw Calls.

    Draw Calls

    So what's a Draw Call? Basically a Draw Call sends all the information about the textures, materials and shaders to the graphics engine. There is an overhead associated with each call, so the lower the number, the better.

    Each time a new material is used in your mesh, it potentially costs another draw call (unless it is a shared material but we will get to that later). The more draw calls the engine has to perform, the more likely you will reach a "bottleneck" and performance will suffer.

    It is also worth noting that the benefits of reducing draw calls decreases as polygon count increases. In fact, you can't have a 100k mesh with a single draw call - the game won't allow it.

    Materials

    Materials define what is rendered onto the mesh. Each material consists of a material type, textures, and other configuration settings. If you change any of these settings you need to use a new material.

    We have many material types in Trainz right now, and we're expanding that set with the new "PBR" materials for the next Trainz product:

    For the example below we will use a new PBR material – m.pbrmetal.

    Here you can see that our material is made up of 3 textures. (See this link on Material Types for more detailed information)


    Click to enlarge

    We applied this material to our mesh (in this case a cube) and now, if we render that in-game it will have a single draw call as we have exactly one material being rendered.


    Click to enlarge

    Now we'll go ahead and add another material on one side of the cube:


    Click to enlarge

    You can see in-game it is now costing us 2 draw calls as we have now applied 2 materials to the mesh:


    Click to enlarge

    NOTE: Trainz utilizes a system called "Mesh-stitching" which allows certain meshes in a scene that use the same material to be stitched together. There are certain conditions to determine whether assets will be included in the stitching process. You can read more about mesh-stitching here.

    Shared Materials

    When multiple mesh files in a single asset use the same material names, these materials are "shared" between the meshes. This increases efficiency by allowing mesh-stitching between the various meshes and reducing the number of draw calls. Without shared materials, each mesh could stitch individually but not against other meshes. Even where mesh-stitching isn't applicable, there are some efficiency gains by using multiple instances of the same material rather than using multiple separate materials.

    In the next example I've taken a cube mesh and a sphere mesh and applied the same material to both meshes. As you can see when rendered in Trainz, there is still only 1 draw call because both assets (or meshes) are sharing the 1 material.


    Click to enlarge

    With Performance Stats enabled in Surveyor (Settings > General Settings > Show Performance Statistics in Surveyor) we can see that Stitched Materials = 1, meaning only one draw call. Remember, this only works if the meshes pass a set of conditions outlined in the mesh-stitching Suitability section.

    Next Week

    Next week we're going to explore a couple of additional optimisations that will further improve the performance of your content. Stay tuned to find out about using Texture Atlases and Mesh Libraries.

    For more information on future Trainz development be sure to keep up-to-date at http://trainzportal.com or see all the articles and have your say forums.

    All content creators wanting to start to look into the technique will find some initial information on the Trainz wiki
    Comments 25 Comments
    1. Dinorius_Redundicus's Avatar
      Dinorius_Redundicus -
      Fascinating (really). I love how these blog lessons address important and complex stuff while keeping the explanations short, simple and pictorial.

      I can follow everything said in this one, except for this little bombshell; "It is also worth noting that the benefits of reducing draw calls decreases as polygon count increases. In fact, you can't have a 100k mesh with a single draw call - the game won't allow it."

      It seems to contradict everything Windwalkr and others have been telling us for years about using as few materials as possible, put all your images into just one file if you can, etc. So I was expecting the article to elaborate but on this point, it leaves me none the wiser .
    1. WindWalkr's Avatar
      WindWalkr -
      It doesn't contradict anything we've said before. Perhaps you're reading too much into the statement? The benefits decrease to some extent, but they don't go away.


      At 1k vertices, going from 2 materials to 1 will roughly double your performance. Going from 10 materials to 1 could give you a 10x performance boost.

      At 100k vertices, going from 2 materials to 1 won't even save you a draw call. Going from 10 materials to 1 will save you a few draw calls, but the benefits are relatively low compared to the vertex cost. Going from 100 materials to 10 is still very worthwhile.
    1. java23's Avatar
      java23 -
      Hi guys,
      EXCELLENT lesson with illustrated examples !!
      Suggestion : make the illustrations a little larger : it's hard to read the labeled texts ...
      Question : what is this tiny little turquoise dot named "Map #4 bitmap" ? I can't guess its origin ? Where does it came from ?
      Cheers,
      Philippe
    1. Dinorius_Redundicus's Avatar
      Dinorius_Redundicus -
      @ java23

      That small map controls glossiness.

      Double-click on the pictures and it should open up full-sized images in another browser tab (or window).
    1. ish6's Avatar
      ish6 -
      Morning All --
      Interesting!
      Ish
    1. Tony_Hilliam's Avatar
      Tony_Hilliam -
      Quote Originally Posted by java23 View Post
      Hi guys,
      EXCELLENT lesson with illustrated examples !!
      Suggestion : make the illustrations a little larger : it's hard to read the labeled texts ...
      Question : what is this tiny little turquoise dot named "Map #4 bitmap" ? I can't guess its origin ? Where does it came from ?
      Cheers,
      Philippe

      Suggestion: Click on the image to get a full size version

      (also added some text to indicate they are clickable)
    1. java23's Avatar
      java23 -
      Hi Deane and Tony,
      Thank you ! I knew that, but I find that, in the full size version, the text is hardly readable, especially on the gray labels ...
      Cheers,
      Philippe
    1. Dinorius_Redundicus's Avatar
      Dinorius_Redundicus -
      Me too. After opening those pictures in a separate browser window, I needed to use the "Zoom" function to make the images larger.


      .
    1. clam1952's Avatar
      clam1952 -
      ctrl + mousewheel here...
    1. pcas1986's Avatar
      pcas1986 -
      Quote Originally Posted by WindWalkr View Post
      ....

      At 100k vertices, going from 2 materials to 1 won't even save you a draw call. Going from 10 materials to 1 will save you a few draw calls, but the benefits are relatively low compared to the vertex cost. Going from 100 materials to 10 is still very worthwhile.
      I thought that the poly (tri) count was still a factor in the draw call count. 100k polys, with all that supporting data, must be a significant "chunk" (pun intended!) of memory.

      I like the series of articles as it confirms much of what I have managed to glean from many posts by Chris, Paul, Zec and others. Perhaps we need to revisit some of the HowTos to draw this all together. Or maybe add some new ones.

      What about adding some help "hooks" to Preview Asset back to the WiKi reference pages and/or articles?
    1. WindWalkr's Avatar
      WindWalkr -
      I thought that the poly (tri) count was still a factor in the draw call count. 100k polys, with all that supporting data, must be a significant "chunk" (pun intended!) of memory.


      I'm not really sure what you're getting at here. Poly count and draw call count are basically unrelated. Both affect performance though.

      chris
    1. Mick_Berg's Avatar
      Mick_Berg -
      Quote Originally Posted by Dinorius_Redundicus View Post
      Me too. After opening those pictures in a separate browser window, I needed to use the "Zoom" function to make the images larger.


      .
      I'm looking at this on an inexpensive tablet and after double-clicking in the images they are perfectly clear. And I am due for a cataract operation!
      Mind you that doesn't mean I have the slightest idea what you guys are on about, well I sort of do...................I'll get my coat...........
      Mick
    1. Mick_Berg's Avatar
      Mick_Berg -
      Sorry double-post.
    1. Mick_Berg's Avatar
      Mick_Berg -
      Reading the Wiki on efficiency in content creation, I see we are only supposed to use a normal map on the first LOD level. How do we do that without using another material? And anyway the normal map is there, so why not just use it at all LODs?

      Thanks,
      Mick
    1. pcas1986's Avatar
      pcas1986 -
      Quote Originally Posted by WindWalkr View Post
      I'm not really sure what you're getting at here. Poly count and draw call count are basically unrelated. Both affect performance though.

      chris[/COLOR]
      Put simply, I thought there was a limit of polys per chunk, and each extra chunk caused an additional draw call.

      I'm probably confused again.
    1. WindWalkr's Avatar
      WindWalkr -
      Quote Originally Posted by Mick_Berg View Post
      Reading the Wiki on efficiency in content creation, I see we are only supposed to use a normal map on the first LOD level. How do we do that without using another material? And anyway the normal map is there, so why not just use it at all LODs?
      That sounds like pretty old advice, probably dating back to 2009 or earlier. The objective was probably to reserve higher-cost materials for geometry that was close to the observer, and use cheaper materials in the distance where the difference isn't as noticeable. That's possible "without using another material" because you're probably already switching materials at some point in your LOD chain, so ensuring that the new material is not normal-mapped is free. However, it's definitely not advice that I'd recommend today:

      * The cost of normal mapping is entirely trivial compared to everything else we're doing in the TANE shaders. There is a slight increase in texture bandwidth requirements, but given that we're talking about distant LODs, you're probably either going to be using smaller texture or a low MIP anyway, so this doesn't amount to much.
      * The material savings are per-fragment; not per-polygon, per-vertex or per-mesh. Since there are typically far less fragments on a distant object, you're unlikely to save much by optimizing the material. An exception would be if there was massive overdraw (which should generally be avoided anyway) or if the majority of the screen was occluded by thousands of repeats of the object in question (eg. a tree).
      * With modern techniques, the benefits of normal mapping far outweigh the costs. A non-scientific example: if you can save 1% performance but it costs you 50% visual quality, that's not a good tradeoff. Worse, losing the normal map is likely to mean that you'll require more vertices and polygons to compensate visually, and that WILL cost you noticeable performance.

      Short version, don't do this any more. If you'd like to point me to the relevant section on our wiki, I'll update it (or you can).

      chris
    1. WindWalkr's Avatar
      WindWalkr -
      Quote Originally Posted by pcas1986 View Post
      Put simply, I thought there was a limit of polys per chunk, and each extra chunk caused an additional draw call.
      No, you're right, which is why I stated that reducing material count on that large a mesh wouldn't reduce draw calls. To explain in more detail:

      * If you have 100k polygons, then you pretty much mush have at least two draw calls.
      * If you're using 2 materials, then you MUST have at least two draw calls.
      * If you're subdividing efficiently, then you will have Material A with ~50k polygons, and Material B with ~50k polygons. That's two draw calls. Even if you replace the materials with an atlas, you still run into the polygon limits and end up with two draw calls, so you've failed to save a draw call. There are other reasons to avoid unnecessary materials, but they're less important. Still a good thing to do if you can, but not as critical as saving a draw call.
      * If your subdivision is inefficient, you might have Material A with ~30k polygons, and Material B with ~70k polygons. That's three draw calls (~30k and ~65k + ~5k). Using an atlas will get you back to two draw calls, so that's a win.

      (Note: the limit is actually on the number of vertices in the chunk's vertex buffer, rather than the polygon count.)

      chris
    1. pcas1986's Avatar
      pcas1986 -
      Great answers, to both Mick's question and mine. VMT.

      The third and fourth points you made in response to mine are thought provoking. There is a UV Mapping atlas addon tool for Blender that some of us have been using to map different meshes to a single texture map. I'm hoping it can be used to implement the texture atlas as described in the new WiKi page on that subject.
    1. Mick_Berg's Avatar
      Mick_Berg -
      Likewise thanks for a thorough and clear explanation.

      I can't immediately find the article about LOD that said to only normal map the highest quality mesh. (This is a common problem for me and the Wiki, getting back to items I want to read again).

      I will find it, but in the meantime it discusses building a locomotive, with illustrations, if that's a clue to anyone about where it can be found.

      Mick
    1. WindWalkr's Avatar
      WindWalkr -
      This page maybe? If so, it doesn't actually instruct you to do that, just gives it as an example. I can see how that you might take that as the "right approach" by implication though.

      chris