I am creating a blueprint that relies heavily on altering values of an instanced materials in the construction script editor.
I am wondering following situation: (Instanced materials are created in blueprint, and doesn’t have a “content editor” counterpart)
I create material instance “A” and apply it to the mesh.
I find out i want to instance another material, so i create material instance “B” and apply this to the mesh.
Since instance “A”, is no longer in use, and is not being referenced anywhere, does it still reside within the system somehow, and thus consume any of the computers resources?
The purpose of the question being:
Can i go nuts in the construction editor, and create an instance everytime a change (move, scale, variable change…) occurs to the mesh.
Or should i make the script so that i keep the number of instances as small as possible?
As i understand it, only the original material gets compiled. Which, as far as my knowledge goes, means that this is the only item consuming resources. But how about in game. If i store X number of dynamic instances in an array, these must be bound to consume some kind of memory, but i still didn’t figure out completely, if the material is completely purged from the memory the moment it isn’t used by anything, or do the adjustable variables still lie as a piece af data afterwards, and thus pile up after each iteration the material goes through?
Or is my understanding totally off bat?
They take some memory of course, but the main advantage is that they reduce draw calls. All MI’s of each other share the same Draw Call as the master material.
EDIT: Not true… see post #7
If a Material Instance is created and there are no longer any references to it, it’ll be marked for kill and picked up by the garbage collector next time it does a pass. By default that’s every 60 seconds - the same as any other non-referenced object. If MI’s are in an array then they are referenced by the array, and therefore they stick around. Dynamic Material Instances are instantiated as new objects, so yes they do take up some memory of their own.
Regardless of whether it’s being drawn to screen or not, if it’s in play, then it’s in memory. If you change the default material on an object in-gameplay, then the original material is still loaded (I believe) - because the master asset has a reference to that material.
If you’re creating new MI’s everytime you change a small factor, then you’re just filling up memory with dead objects that will need to be Garbage Collected, and it can (and likely will) cause the engine/game to hang while it deletes them all. Worst case scenario is you get a memory leak and run out of memory. The idea of Material Instances is that you change properties though, so I’m not sure why you need to create a new one each time anyway, just modify the properties of the existing one.
Thank you for a well written reply
Exactly the answer i needed. It was to find out, if i in my blueprint could just create away on the materials (the easier way), or if i should work around it, and keep track of the materials and their instances i used. It was in the case in which i create an MI, and store it in an array. Then a change might be occuring in that MI from the blueprint, but i also might need to change the base material and be able to work on an instance of that too, and keep switching back and forth seamlessly between these base materials without it consuming more memory than needed.
Material instances does not ever share draw call with the master material. Only Instanced Static Meshes share draw call and limitation is to use same material for all instances.
Are you sure? I’ve been told otherwise many times That would suck if that wasn’t the case…
EDIT: Well well, I stand corrected! However it appears as though mesh components are sorted by Material and go down a faster render path if they share the same master, so there’s still benefit of sharing.