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

Avoiding Duplicate Texture Loads

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

  1. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    658
    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:
    38,517
    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.
     
    SparrowGS and stonstad like this.
  3. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    658
    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:
    452
    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:
    658
    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...