No announcement yet.

X materials on a mesh mean mesh renders X times?

  • Filter
  • Time
  • Show
Clear All
new posts

    X materials on a mesh mean mesh renders X times?

    Mentioned here:

    "Whenever you have 2 materials applied to an object, the GPU has to render that mesh twice..."

    How true is this? I'm currently working on modular buildings, and plan to reuse 3-4 textures on many different buildings (as I've seen others do). Will this mean that a building using 4 textures will have 4x tris?


    Ryan is close. What happens in this case, is that the mesh with two materials would count as two draw calls.

    For example, if you have a car and it has metal and glass as its materials. The mesh would require two draw calls instead of one. The number of draw calls is quite important on lower end GPUs and mobile devices. But in general, if you can reduce the number of draw calls in any particular scene the better.

    Draw calls are a set on instructions to send to a GPU to render something. Since you have two materials on one mesh, you can't tell a card to do both materials at once (shader pipeline). You tell it to do one shader first, and then tell it to do another shaders.

    This problem can be exponential. Say you have a mesh with four materials applied to it. If you have fifty of these meshes in a scene, it isn't fifty draw calls. It's fifty multiplied by four, which results in two hundred draw calls.

    Textures used by a material doesn't consume draw calls, but you can only have a certain number of them per material. A material which uses more textures just consumes more memory required to use the material.


      That was quick.

      So lowering amount of draw calls is better optimisation overall than having lower texture sizes? What I mean is, would it be better to slap all 4 textures into 1 (let's say 4 512x512 textures into 1 2048x2048), and use one material for all the buildings, rather than four different ones?


        Well, what you have here is a cost between memory and run time performance.

        For example, let's say you have a brick wall. Each brick is a single model and you duplicate it a hundred times to form the wall. Great for memory as there is only one mesh in memory, but bad for run time performance as you have to send a hundred draw calls to render the wall. So you need to find a balance by making the brick wall composed of tileable sections of static meshes instead.

        Therefore, it isn't a comparable optimization to reduce draw calls to reducing memory. Memory is a hard ceiling, as the player only has so much memory or video memory in their system. Performance is all over the place as it depends on the CPU and GPU that the player has.

        You could try using one material for all of the buildings, and it will be faster; but I don't know if you will get enough variation. Texture atlasing does provide better performance for the shader as there is less texture look ups that you need to do... but it isn't a huge concern these days since most shaders usually use three or four textures at minimum these days.

        At the end of the day, like programming, early optimization is the root of all evil. Build the game first, if it runs slow, then look at how you can improve performance. A completed level tends to suffer in performance for larger things.


          Great answer! I think I'm starting to wrap my head around it.

          I think really starting to worry about optimization early being bad sounds right.

          Just to get something straight; using one material for the buildings will improve run time performance? Texture sizes for this material doesn't really matter for this (let's say a dif, spec and normal-map at 2048)? The only concern then is variation in the textures itself?


            "... the GPU has to render that mesh twice"

            Technically, the entire mesh is not rendered twice.
            The mesh is split into two, only the faces with material x are in one drawcall, and only the faces with material y are in another drawcall.
            Depending on the frustum contents and the mesh and material, it may also be batched with other objects into the same drawcall.

            "So lowering amount of draw calls is better optimisation overall than having lower texture sizes?"

            Unfortunately it isn't that simple.
            In a 3D engine a typical frame can easily have 10,000+ drawcalls. Where you sit depends entirely on your map and object design.
            If you had good drawcall optimization, but you were using all 4096 or 8192 textures and a lot of them, you may run out of texture pool on cards under a certain memory size eg. 1GB cards and under, and then the renderer has to fetch textures from system memory per-frame, which is a large performance hit as the large amount of texture data is passed over the PCIe bus at slower speed.

            Another issue to consider with textures is that you must (should) match up the texel size between mesh objects as closely as possible, or the scene looks poor and amateur.

            Back when we were developing content for earlier UT and UE2/UE3 games, we used a set of grid textures that were from 64x64 to 2048x2048 marked off with each of the texture sizes in a grid.
            Then we would initially apply those textures to objects that were created in CSG or meshes that were imported, so that the UV mapping scale could be checked for final comparable texel size, and then the object UVs adjusted if required, or a change to the texture used for the object either larger or resampled smaller.
            Later UEngine versions added the Texture Density viewport mode which aids somewhat in showing whether meshes have close or disparate texel densities.

            To give an example, if you decided to use 2048 textures on everything, then a car vs a wrench would look bad in-game, as the wrench would have very high definition due to its finer texel size.
            Similarly with your buildings. If your walls vs windows vs doors were individual meshes with individual textures, you need to choose the proper texture resolution for each object so that in-game their texel size is similar. Otherwise for example the doors and windows may look very clean and defined up close but the walls look all blurry.

            It is often easier though to reduce texture resolution than to reduce poly/vertex count on meshes.
            So starting out with high-resolution textures allows room to easily resample them smaller and re-import them.

            I think really starting to worry about optimization early being bad sounds right.

            It takes some experience using the engine to better determine the starting point for each mesh poly count and required texture resolutions.
            Depending on your experience level with UDK, look at the content that comes with it, play around for a day or two placing different meshes into a scene, look at the poly count and texture resolutions used by the content, and it should give you a starting point.

            ... using one material for the buildings will improve run time performance?

            That question cannot be answered without the context of the entire map and what is currently in the frustum.
            See my comment above regarding texture memory pool etc.
            It will also depend on whether it can be batched or not.

            You may also run into issues with comparative texel size.
            The building may look blurry when standing next to it, while all decorations inside and outside may look better due to finer texel resolution.

            Texture sizes for this material doesn't really matter for this

            See my comment above regarding texel size.