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

I need clarification on materials, texture atlas and why I am confused Please help

Discussion in 'Shaders' started by Unlimited_Energy, Mar 10, 2017.

  1. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    ok, so Texture atlasing and batching seemed confusing to me at first. I read that you should share the same materials across as many objects in your game as you can so that you can create texture atlases and batch them. I was assuming a material ment textures with the material too thinking o thats stupid because I really cannot use leaf textures on rocks and ground textures on my character thinking how are you suppose to re use all these different looking materials.

    I read in unity docs that you can have the same material but different textures. Im confused now a little please clarify. When it states share the same material across as many objects as possible to create texture atlases, is it saying I can create one material wit the same shader, same rendering mode selection and shader values but I can change the texture? so is it essentially saying use the same shader across as many objects as possible? I mean a material is a shader and maps with a render mode selection.

    Do you see where I am confused.... I feel like im missing out on massive performance I could be taking advantage of but I dont understand what they mean by use the same materials but can have different textures. I create a different material for each object in my game that has a different texture/maps.....
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    For batching to work it has to be the same material. And by same material I mean explicitly a single material asset. If you make a copy of the material and change a value, those two materials can't be batched. Actually if you make a copy of a material and change nothing it still will not batch together. If you have a material and change a property on it at runtime, the game creates a new material dynamically, and it'll break batching. If you have a material and add a material property block to modify the properties with out causing a new material to be generated, like what Unity does with sprites and animations that are used on materials, this will also break batching. If a mesh is dynamically lit and has a dynamic light touching it, or if your scene is using light probes and the object isn't using lightmaps, this also breaks batching as internally Unity is effectively using different materials for each part.

    The reason for all of this is because what batching actually does is just take multiple meshes and combines them into a single mesh. This is beneficial because GPUs render mesh one at a time, and only using one shader and set of properties at a time. Those properties include the textures and other properties on the material, but also the object's position, the lighting information, and much more.

    I'm curious where in the documentation you saw "same material, different textures." I'm assuming as part of the sprite documentation, and it is indeed more efficient to be able to use a single material like that and change just the texture (using the material property blocks I mentioned before), but this isn't because of batching entirely. Unity's sprite system uses atlases it generates so you supply the sprite you want and it'll automatically chose the texture needed, and Unity's rendering systems are slightly faster when you don't have hundreds of individual materials and instead override a single material using material property blocks. It's a very small benefit so it only really becomes a problem on mobile where the CPU time is limited.
     
    Unlimited_Energy likes this.
  3. Unlimited_Energy

    Unlimited_Energy

    Joined:
    Jul 10, 2014
    Posts:
    469
    https://docs.unity3d.com/Manual/DrawCallBatching.html

    "Material set-up for batching

    Only GameObjects sharing the same Material can be batched together. Therefore, if you want to achieve good batching, you should aim to share Materials among as many different GameObjects as possible.

    If you have two identical Materials which differ only in Texture, you can combine those Textures into a single big Texture. This process is often called Texture atlasing (see the Wikipedia page on Texture atlases for more information). Once Textures are in the same atlas, you can use a single Material instead."


    OOo so I guess I'm confused then how to use a single material and having the object be assigned the right texture from the atlas. So I basically would assign as many objects a material and then somehow assign the correct material from the "position" within the atlas....
     
    AldeRoberge likes this.
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Your meshes' texture UVs. Just like you might have a character with a single texture that includes the face, body, hands, and feet all in one texture, that texture now also includes a wooden box, a house roof, various walls, etc, etc.

    There's nothing built in to Unity for this for 3d meshes, this is something you have to do manually in your own, or there are a few assets on the store that'll do (most of) the work for you. Basically take several objects that are already textured, put all of those textures in a larger texture, then adjust all of those objects' UVs by scaling then down and moving them to the appropriate party of the big texture.

    If you're unfamiliar with texture UVs start there.
     
    vozcn likes this.
  5. nasserr

    nasserr

    Joined:
    Aug 4, 2017
    Posts:
    1
    If I understand correctly... If I have a copy of an object copied a thousand times. And all of them share the same material. Them if I add a script to the prefab. Using material properly blocks to remap the uvs on each single object... Would that break the batching?
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    That would break batching, but would be a good case for instancing (though it would require a custom shader as the texture scale &a offset values are not instanced properties by default).

    You could use https://docs.unity3d.com/ScriptReference/MeshRenderer-additionalVertexStreams.html instead to do this in a batching friendly way, but if these are values you plan on animating you'd probably want to use instancing instead.