I am trying to batch-draw objects with DrawMeshInstanced. They all have same mesh and material, except I need to set them different _MainTex_ST (to implement texture cycling) per instance, without breaking batching.
What I do now - I pass a MaterialPropertyBlocks parameter to DrawMeshInstanced, with an array of Vector4 values that holds a value for _MainTex_ST property of each object:
var propBlock = new MaterialPropertyBlock();
int texScaleOffsetPropertyId = Shader.PropertyToID("_MainTex_ST");
Vector4 ScaleOffset(float offset) => new Vector4(1, 1, 0, offset);
propBlock.SetVectorArray(texScaleOffsetPropertyId, new Vector4[2] { ScaleOffset(0.6f), ScaleOffset(0) });
var mesh = GetComponent<MeshFilter>().mesh;
var material = GetComponent<Renderer>().material;
var transforms = new Matrix4x4[] {
Matrix4x4.TRS(transform.position + Vector3.right, Quaternion.identity, Vector3.one),
Matrix4x4.TRS(transform.position + Vector3.right * 2, Quaternion.identity, Vector3.one),
};
Graphics.DrawMeshInstanced(mesh, 0, material, transforms, transforms.Length, propBlock);
However, as a result I get this:
all models (2 in the example) are rendered with the value of the first element of property block array - seems like all the others are ignored. Batching still works - only 1 draw call for DrawMeshInstanced call.
Am I doing something wrong? Or is this the limitation of batching in unity - are per-instance material properties not supported?
Is the custom shader required to access those per-instance properties from MaterialPropertyBlocks?
P.S I tried this in both URP and Built-in, just to be sure. Same effect.