Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Avoiding Duplicate Texture Loads

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

  1. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    38
    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,026
    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:
    38
    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:
    412
    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:
    38
    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...