Guys,
I feel it’s a point to take a look at URP, looks like there’s no reason it should be that different, so I am sharing in case someone knows a reason for it or if Unity Team wants to take a look.
I am getting a gigantic performance difference between the properties material and materials:
material takes some nanoseconds
this.MeshRenderer.material = tileDefinition.material;
materials is taking hundred times more and showing thousand GC.Alloc instances on profiler
var materials = this.MeshRenderer.materials;
materials[0] = material1;
materials[1] = material2;
this.MeshRenderer.materials = materials;
On this picture I called this 4 lines of materials around 15-20 times and got 4.32ms for this, while using material to the same objects It does not even appear on my profile, It’s a gigantic difference.
Profiling with StopWatch to get how many ticks elapsed:
ElapsedTicks Single Material: 9
ElapsedTicks Materials: 537 (50 times higher cost)
When you access Renderer.materials Unity creates a copy of the array to return, which allocates garbage as you see. This is true for all Unity getters and methods which return arrays.
Worse yet: when you read the materials array for the first time, Unity creates copies of the materials in the sharedMaterials array, so you can change their properties without affecting other meshes using the same materials. Unity does not destroys those materials, they will remain in memory until you either manually destroy them, load a non-additive scene, or call unloadUnusedResources.