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:

{{0xc000a0a500 0xc000a0a500 image-1.png  alt text alt text 0xc00077dce0} 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.

{{0xc000a0a500 0xc000a0a500 image.png  alt text alt text 0xc000629140} 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:

{{0xc000a0a500 0xc000a0a500 image-2.png  alt text alt text 0xc0008540c0} 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


{{0xc000a0a500 0xc000a0a500 image-3.png  alt text alt text 0xc0008544e0} 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:

{{0xc000a0a500 0xc000a0a500 image-4.png  alt text alt text 0xc0008552c0} 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.