- Home /
Substance Material - Clone at Runtime (Mobile)
Hello,
I want to be able to have 40 Instances of my model but each with unique colours that is generated by script, at runtime.
The issue I'm running into is a massive overhaul on memory (this is running on the latest iPhone).
Firstly, I've duplicated by model 40 times, and placed in a grid. I then need to clone from the master ProceduralMaterial in order to be able to uniquely change properties for each individual model. I do this by calling this on every instance of my model:
//gets the master from this renderer object
_clone = (ProceduralMaterial)_renderer.material;
//apply the new clone to this renderer object
_renderer.material = _clone;
//change a property on the clone material
_clone.SetProceduralColor("some_property", _randomColor);
//and build
_clone.RebuildTextures();
This works, however the memory usage increases massively (from 115Mb to nearly 300Mb). The Substance Material has a Generated Texture applied to it.
Is this spike in memory because of Substance having to Duplicate this Texture each time I clone the material?
Thanks.
Answer by DevsGoingViral · Jan 11, 2017 at 03:01 AM
Hi,i'm substance designer user.Each time you change properties of substance during runtime it will every time rebuild whole graph(so it is wise for realtime changes with substances to have really well optimized substance for such usage-quck generation of textures).Problem you have is 40 models=40 substance instances = 40* whole texture set each time. It is massive in case of generating all that textures and even when calculated you will have crazy amount of textures.Depending on world size and importance and camera distance from the 3D object you should join all 3D objects into one substance and create masks inside graph which will help you to separate colors for every 3D object.If you don't need to generate all objects textures in realtime in front of players eyes then you can specify when they will rebuild and on such way you can scatter processing power while they generate textures(generate -if in player range,generate after "x" seconds and so on....).If you doing some optimization for 3D objects for example if you spawn object and generate texture,you record texture into device solid drive,then you unload such texture and do everything again with next 3D object
continued.....that's fine.Hope this helps.Also make sure you didn't missed something from documentation: https://docs.unity3d.com/$$anonymous$$anual/Procedural$$anonymous$$aterials-Caching.html
Hello, thanks for your answer. Very helpful. So in a short answer - it's not wise for me to clone these materials for customisation per model?
The processing time it takes to calculate the new Textures isn't a problem for me - as this can occur 'during game loading' - It's the memory in the background that is an issue.
I don't know that much about Substance - but I'm wondering if it's possible to split the mesh of the model: So the Substance mesh (with Procedural $$anonymous$$aterial, etc) is one part of the model - which is NOT duplicated, and then the mesh that needs to be customised is just using default Unity $$anonymous$$aterials - thus I can change a colour through the $$anonymous$$aterial properties, and not having to regenerate a new Texture.
I'm glad i was able to clear at least some stuff out.Yeah you will end up with 40 materials and if substance is PBR that means * around 3 Textures which as result should not run on mobile. Number of materials and number of textures is GPU killer.Even if you wanted to arrange level_design and script tons of optimization in such way that loading only few textures into gpu is possible per distance/player view is possible but that's to much work,and when i look at you post now i see they are arranged into grid and i assume they are all inside player view so basically you can't use level design or code in your advantage.
Sure you can build textures on load time but inside level if only one change is introduced to substance it will rebuild itself completely in order to generate new texture set-when they stretch muscles like that they will consume cpu while generating,when cpu is in struggle to compute something he will throw such thing into memory on hold,at least i think this happens to you - constant or in a row substance rebuilding will consume cpu and memory and that's what you encounter.Someone can correct me if i'm wrong.
Yes it is possible to split mesh on such way.Yeah if color is only thing you want to change what you suggested is one possible solution.But i'm still concerned about all that 40 materials that will need to be there to change now only color.I see you want random color so ins$$anonymous$$d of 40 materials to achieve that you can use only one material and all meshes which needs to change color will share one Uv space and painted atlas with different colors and offsetting him will mimic random colors for you - but in this case all objects with change-able color will get all in same time "random color".
However this can be done with only one dedicated substance for your usage-and you can access them with your scripts inside this one substance.Color parameters designer/person was exposed for you and individual customization of all meshes is possible with that one material - also downside of this is graph/code inside substance will become larger(to handle 40 meshes customization) so it can allow you individual changes which will result in more waiting until substance calculate all that for you-so you can encounter lag(depending on substance resolution this can be additionally lower or higher). But like i mentioned highly optimized substance is required. I'm willing to help you further,just e-mail me. \e/ I think with 2*4$$anonymous$$ px(latest iPhone should support this resolution) or 4*2$$anonymous$$ px substances you can have what you wanted and on this way we balanced between cpu and gpu(of course this applies if this 40 objects is main feature of the game). -On this way we splited size of substance graph so when generating it will do it faster. Of course i can't be smart on this one just like that,testiing is required.For example comparing 40 material realtime changes VS our new substance and see which performs better and have less impact on cpu or gpu .
Also don't forget Unity batches meshes which uses same material so CPU usage is optimized with low number of materials used across meshes.
And if you talked about GPU memory that's easy answer,that's because when substance is instanced every such material will have each own textures so gpu spike is because 120 textures you have there :) .
Your answer
![](https://koobas.hobune.stream/wayback/20220612104549im_/https://answers.unity.com/themes/thub/images/avi.jpg)