Search Unity

Avoiding Duplicate Texture Loads

Discussion in 'Scripting' started by stonstad, Jan 11, 2019.

  1. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    81
    I'm hoping someone might know what happens internally in Unity given the following scenario --

    If I create a game object from a prefab and then change a material on an instance of that prefab -- all within the same single update tick (and just once), will the original material's binary texture data be loaded?

    Here's an example of what I'm doing:
    Code (CSharp):
    1. GameObject prefab = Resources.Load<GameObject>("path");
    2. GameObject instance = Instantiate(prefab);
    3.  
    4. MeshRenderer meshRenderer = instance.GetComponent<MeshRenderer>();
    5. Debug.Log(meshRenderer.material.mainTexture.name); // "original.png"
    6.  
    7. meshRenderer.material = newMaterial;
    8. Debug.Log(meshRenderer.material.mainTexture.name); // "new.png"

    So to be really clear, does this code load texture binary data twice-- once for "original.png" and twice for "new.png" ...

    or is loading binary texture data deferred until a render tick?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    3,684
    When you hit Resources.Load(), everything necessary to bring that asset (textures, materials, meshes, etc.) up is accessed... in some form. For instance with audio data, it might only load the header if the audio is marked for streaming.

    And then when you instantiate it, at that point it is ready for business (Awake and OnEnable have been called), so original is definitely loaded.

    If you're genuinely concerned about the bandwidth of two full-sized textures loaded, then make a 32x32 placeholder and store that in your prefab, then just ALWAYs replace it.

    Generally when you get below the API like this you can't know what's happening for sure.

    It may vary from platform to platform, and it may vary from version to version of either the Unity engine used, or the operating system involved.
     
    SparrowsNest and stonstad like this.
  3. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    81
    Thanks @Kurt-Dekker. Your explanation is super helpful. I am going to go the route of creating placeholder textures so that I do not incur the hit of a duplicate texture load. Thank you!
     
  4. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    426
    You don't need placeholder textures in your example. Unity's materials use flyweight. The texture data will only be loaded once. You may have extra material objects floating around after using the renderer.material property, but the beefy texture data will be shared.

    This answer doesn't necessarily apply to items loaded via asset bundles, however.
     
  5. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    81
    Admittedly, this is what I was hoping for. OK, so based on the code example above, binary data associated with texture "original" is never loaded (even initially) since a material changed occurred prior to render...