They might sound similar but are actually two different things. You can both use them to reduce draw calls and still provide per instance material control on meshes.
Per primitive data is available on all primitives and per Instance Data on ISM and HISM.
But! ISM are also primitives so you can use them both! Primitive data will apply to all instances in the component and instance custom data per instance.
There is a system called auto instancing in UE and so you can use static meshes with primitive data and still have them as one draw call per LOD.
To check if instancing is working correctly I can recommend render doc. I saw the behavior that ISM will draw together if they have the same amount of instances. (For non nanite)
To use primitve data in a material: Make a scalar or vector parameter and there is a checkbox for it.
To use instance data in a material: there is a seperate node for it. (PerInstanceCustomData)
That had me kinda confused as well. Found this article on the whole process and figured out that I’d forgotten to set the “Num Custom Data Floats” variable on the instanced component. Hopefully you’ll be able to spot what you’re missing from it.
TL;DR the most important parts are the “Set Custom Data Value” BP node, “PerInstanceCustomData” material node, and setting the “Num Custom Data Floats” on the instanced component.
CPM is a great thing, but unfortunately unusable thanks to Epic, which still does not support packed level actors. They know about it, but its not their “priority”. So its another nice thing throwed to trash, because they doesnt care about bugs.