Reduce instance count of UInstancedStaticMeshComponent

I’m drawing instanced meshes, and I want to make the last N instances invisible for a period of time. Is there no way to tell the UInstancedStaticMeshComponent to do the draw call with fewer instances? I don’t want to call RemoveInstance and incur all the cost of updating transforms and reorganizing memory, as I want the extra transforms to remain allocated. I literally just want the component to issue its draw call with fewer instances specified.

This seems like a duplicate of this question, which doesn’t bode well for me finding a better solution then giving those instances a 0 scale or some other hack like that… but does anyone have a better solution?

Hi, one thing that come into my mind is to use masked material and change opacity to 0/1 depending on PerInstanceCustomData.
I use this to change colors for instances, but could be used to make some of them invisible.

In short use this in BP.
HISM Component Details:


BP logic:

And more or less something like this in material:

And should work. If you want to implement this solution and something is not working well, just let me know and I can explain it in more details.

Hooking it into a mask might be cheaper performance wise. (blend mode: Masked)
It’s cheaper as it discards the material from calculations at a much lower threshold.

Right, so no way to simply reduce the count of instances. That’s pretty frustrating and should frankly be available to us, unless the transform buffers aren’t in the same order as the instances…

Regardless, I don’t think I’d want to make these things invisible by messing with the masking or opacity, as that’s going to still transform a full set of vertex data and evaluate a material per-pixel. I think a better bet is to update the individual transform with a zero’d out FTransform (0 scale). Then it’s a one time hit to update it, and should skip any evaluation in the pixel shader. Like this:

		FTransform zero;
		zero.SetIdentityZeroScale();
		instancedMeshes->UpdateInstanceTransform(idx, zero, false, true);

(It’s also worth noting that if you’re going to do this for multiple instances, you should only pass true for that final value (bMarkRenderStateDirty) for the last instance you update, for better performance)