Custom Primitive Data


We want to keep drawcalls down in a game like this - it will likely be the biggest source of optimization pain.

Custom primitive data (and instanced custom primitive data) let us change parameters on meshes or instances without assigning a dynamic material, allowing for reduced complexity at the cost of a little less flexibility. Let’s take a look, using the grid node as an example:

{{0xc000343ef0 0xc000343ef0 image-1.png  alt text alt text 0xc000803da0} 0 false}
First off, let’s combine the node and hover plane into one in Blender, separated by vertex color, not material. I’ve also cut out the pattern into geo for cleaner edges / match style.

{{0xc000343ef0 0xc000343ef0 image.png  alt text alt text 0xc0007e09c0} 1 false}
Let’s make the material. In the material editor, custom primitive data works almost exactly like scalar parameters and share the same node:

{{0xc000343ef0 0xc000343ef0 image-2.png  alt text alt text 0xc000a301e0} 2 false}
In the details panel, check UseCustomPrimitiveData. Unlike dynamic parameters, CPD uses an index (you can make up to 32 per mesh). You can still name the parameter, but you’ll be accessing it via this number.

NOTE: You can easily accidentally use the same value as a different parameter. This is the major downside of CPD, but with planning it should work out. Make sure when working with existing materials you take note of any CPD indexes used and avoid colliding.

Thats more or less it for the material CPD wise.

Code


{{0xc000343ef0 0xc000343ef0 image-3.png  alt text alt text 0xc0007e00c0} 3 false}
In the blueprint, in this case a component, we can make an update function for animation. You do not need to make a dynamic material instance, nor a separate variable for the mat. Instead, we can set CPD directly on the mesh component. In this case, the bp component I am editing IS a primitive component, so I can just target self.

CPD won’t show in editor by default - there is a special node for it:

{{0xc000343ef0 0xc000343ef0 image-4.png  alt text alt text 0xc0007e0480} 4 false}
If you have something you need to be “pre” setup before start (IE construction script), use this node. Be sure to use the regular node for runtime changes though!

There are nodes for “vector”, but all it does is string 2 or more scalars together. Useful for organization, but remember the indexes just act sequentially - no special sorting.

That’s it! The mesh itself contains the scalar value, and can still be instanced (should be automatic by the editor). Check out the official UE docs for more info, but honestly that is pretty much all there is to it.