- Home /
The best way to have multiple models with only one material
Hello,
straight to the point, I have a lot of models in polygonal style, I know for sure that none of these models will have texture. I only need to assign correct colours to the models.
Also some of the models, for example, wooden barrel, will have more colours, for the wood part and for the metal part and I'd like to have the possibility to change the colour of these parts at runtime.
I'm trying to find a way how to use as fewer materials as possible. In previous projects, I achieved this by creating a texture with colours I wanted to use and each model has its own colour assigned via UVs. But in this case, I won't be able to change the colours.
Any ideas how to achieve this? I ask only for ideas, not scripts.
EDIT1: Let's add an example: I have one big table with a lot of items on it: plates, cutlery, cups, etc... Each model has its mesh. What I want to achieve is to have one material for more tables in the scene with the possibility to change the colour of each mesh and each table. Is this somehow possible?
Answer by bunnynsnake · Apr 17, 2018 at 06:06 PM
that is a little strange, im not really sure why you would want to do that. But you might want to try using the events system and rect transfrom with a sprite. then again, im not sure how you have your scene set up. But you might want to check out this video : https://www.youtube.com/watch?v=abZ1EnijrSs or perhaps this : https://www.youtube.com/watch?v=Jvj03I81Pl4
To reduce draw calls in a quite complicated scene on mobile devices, that's why I want to use few materials only.
that makes sense. I am making a mobile game as well, and those videos helped me.
Answer by Remy_Unity · Apr 18, 2018 at 11:34 AM
You basically have two ways to do that :
Have all your objects that support materials using the same shader with gpu instancing enabled, and with the color(s?) parameters that are instance parameters. This will allow the engine to batch objects together and reduce draw calls.
Precompute your color in the mesh data and send it to the material's shader. Use the vertex color for example. This way all objects can have exactly the same material, but each have different data. You can use https://docs.unity3d.com/ScriptReference/MeshRenderer-additionalVertexStreams.html to add datas to your mesh without have to create dupplicates.
So if I'll have 200 materials on 200 meshes using the same shader with instancing support, will that reduce the draw calls?
I've tried the second approach with $$anonymous$$aterialPropertyBlock. I could use only one material on all objects and set a different colour for each object but it would behave the same as if I would have more materials.
Theorically, yes. Will depend of the settings (dynamic/static batching enabled or not, GPU instance enabled or not). See here for infos : https://docs.unity3d.com/$$anonymous$$anual/GPUInstancing.html
Even though it says that $$anonymous$$aterialPropertyBlock doesn't create a new material, it can break your batch. If used on a materials that supports GPU instance, it may work.
$$anonymous$$eshRenderer.additionalVertexStream will change the mesh data when rendering, if your material's shader implement a usage of this data (vertex color for example), then all your meshes cant share exactly the same material, so can be batched together. It's virtually creating new meshes but sharing exactly the same material. It's not the same as $$anonymous$$aterialProperyBlock.