I’m trying to reduce my draw calls, but no matter what I try the singular material I wish to use keeps making instances, and Frame Debugger says “Cannot batch since using different materials”.
So after reading practically everything google had to offer to fix said issue, I’m still at a loss, and can’t understand how to prevent new instances. I’ve tried using sharedMaterial, MaterialPropertyBlocks, and even a custom shader.
A generalized example of my code:
rend = GetComponent<MeshRenderer>();
Material test = rend.sharedMaterial;
//Destroy(rend.material);
rend.material = null;
rend.sharedMaterial = test;
//rend.material = null;
//rend.sharedMaterial = null;
//Destroy(rend.material);
//rend.material.shader = objList.shaderDefault; // NO
//rend.sharedMaterial = objList.shapeDefault;
//rend.sharedMaterial = Instantiate(objList.shapeDefault);
//myPropBlock = objList.propBlock;
myPropBlock = new MaterialPropertyBlock();
myPropBlock.SetColor("_Color", color);
rend.SetPropertyBlock(myPropBlock);
if (rend.HasPropertyBlock()) print("has property block");
As you can see it’s a mess, of trying everything I’ve heard suggested through other posts on this same issue.
And even tried the Unity Manual example of making a shader, that should be appropriate:
Shader "Custom/TestShader"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
// Uses the physically based standard lighting model with shadows enabled for all light types.
#pragma surface surf Standard fullforwardshadows
// Use Shader model 3.0 target
#pragma target 3.0
// added this later? Still not changing anything
#pragma multi_compile_instancing
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
UNITY_INSTANCING_BUFFER_END(Props)
void surf(Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Which is the third attempt of making my own shader, that I just stuck with since I was able to force dynamic batching:
This ^^ is normal runtime of the game, which does show some of the objects being batched. I’m not sure which ones they are, since all of the ones in the hierarchy still show “Material (Instance)” on their shader/material. So I maybe assumed it’s like I read in catlike codings example:
Where he states it may be the issue of too many vertices, and Unity by default will create new instances.
However, if I select all in-game objects, then select the material for all of them, I get:
The shader seems to perfectly fine with batching them all. So I find it hard to believe that that’s my issue.
So is there something wrong with how I’m trying to set the sharedMaterial? Or is there some other default modification I need to disable? Any help, or clarification on any of this would be greatly appreciated, as I am down-right confused on how materials work now.