Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How do I have a single texture for every object?

Discussion in 'General Graphics' started by Kiru176, Jul 15, 2023.

  1. Kiru176

    Kiru176

    Joined:
    Jan 23, 2020
    Posts:
    1
    I was looking for a way to have one shared texture and material for all objects in my game to have minimal calls, but I have no idea how to achieve it. Talking about something like this.

    upload_2022-3-5_20-14-55.png
     
  2. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    547
    This is called a texture atlas.

    While this can in fact be a good way to reduce draw calls and increase performance, it does come with a few downsides as well:
    - There is a maximum texture size (I think it's 8k on PC and 2k on mobile, but could be less on certain hardware). That means, many textures will have to be much more low-res than they'd usually be
    - Tiling (u/v coordinates outside of 0-1 range) is not supported, unless you calculate the u/v coordinate in the pixel shader
    - You need an uber shader (e.g. one that can handle all different lighting models at once like skin/subsurface shading) and some way to specify the lighting model per texel or vertex. However, you can also restrict yourself to using this only for materials with the standard lighting model
    - You need one atlas per texture format, so normal maps might need a separate one
    - Since there is a maximum size for textures, you usually can't have one big texture for everything. So you'd use multiple texture atlases for different group of objects (e.g. a table with items on top). This means, when one texture is needed in multiple atlases, you end up having it in memory multiple times
    - Not compatible with classic texture streaming because that works only on entire textures (but might work with streaming virtual texturing)

    Note that you need to add a border around each texture region to prevent that regions bleed into each other when filtering/mipmapping (probably also for texture compression).

    Usually, texture atlases are created in a DCC tool like Maya or Blender but there are probably plugins that can do this for you within Unity. It's not that hard to do. You just need some sort of bin-packing algorithm and CPU readable meshes.

    So the bottom line is, it's not a bad idea but be aware of the limitations and only use it for groups of objects, not the entire map. It is commonly used on characters, for example. If object composition is done in Unity (e.g. objects with an arrangement of nested prefabs), it's a bit more difficult, because then you need to do the baking within Unity since you don't know the composition in DCC tools.

    PS: The SRP batcher in URP/HDRP makes draw calls cheaper, so texture atlases might not be needed (but I'm skeptical)
     
    Last edited: Jul 16, 2023
    kenamis and tw00275 like this.
  3. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,325
    Basically when you create the objects in your 3D modelling app. you simply need to UV map them to use parts of the same texture. Then in Unity assign the same material to all of them.
     
  4. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    547
    What I forgot to mention:
    To reduce the draw calls, you also have to merge the submeshes (and meshes, if it's more than one), but the tools usually do that for you.

    Also, another reason not to go crazy with this is culling. If you only have one mesh for the entire map, it can only be culled in it's entirety.
     
  5. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    839
    Just wanted to point out my own experience with URPs SRP bratcher here. In one of my tests scenes I have 3600 characters walking around, each with their own unique material on display. In the worst case scenario (everything is on screen) I have over 7k draw calls but only about 30 to 40 set passes. I actually use imposters, each consisting of a unique texture for every one of the characters to improve performance because it's so much faster than rendering skinned meshes with Animators when at a distance.
     
    kenamis and c0d3_m0nk3y like this.