Renderer with multiple materials -- per-material MaterialPropertyBlocks?

I am working with imported assets that have multiple materials per mesh (eg: a single MeshFilter and MeshRenderer, with the MeshRenderer’s materials array containing 2 or more entries). Each Material has a unique albedo texture but shares other parameters with every other material. For Meshes that contain only a single material, I’ve been using MaterialPropertyBlocks to quickly change properties across every material. (I’m ingesting models from photogrammetry software, and adding overlays, different shading strategies, etc – this is data viz in a game engine, not really a ‘game’).

This breaks when Models have two or more Materials, though – I can only set a single MaterialPropertyBlock for the MeshRenderer, so Material[0] gets the correct albedo, but Material[1] through whatever end up sharing that albedo, which of course looks horrible since the UVs are all wrong.

To work around the issue I could create several shaders with texture samplers named eg _MainTex0, _MainTex1, etc, and make sure the variant with _MainTex1 is always assigned to materials[1], etc, but this seems like a silly hack.

Is there a “right” way to get this done?

One workaround option is to call the Graphics.DrawMesh function, rather than using a MeshRenderer component.

This function has versions that take a MaterialPropertyBlock, a Mesh, and a sub-mesh index. So, obviously, you would need to call this function once per sub-mesh.

In my experience, this is far less efficient (speed-wise) than using a MeshFilter and MeshRenderer.

I don’t really LIKE this workaround, I’d rather be able to actually set a particular sub-mesh’s MaterialPropertyBlock, and just use the Regular MeshRenderer, but I just don’t see how- other than breaking up the mesh’s sub-meshs into multiple “full” meshes (and putting them in the scene as their own GameObject, with their own meshFilter and meshRenderer).