Hi, I’d like to report a bug in the instanced static mesh component in regards to motion vectors:
When per-instance previous transforms are enabled (SetHasPerInstancePrevTransforms(true)), the ISM expects as many transforms in PerInstancePrevTransform as there are instances as can be seen in UInstancedStaticMeshComponent::MakeInstanceDataFlags:
Flags.bHasPerInstanceDynamicData = PerInstancePrevTransform.Num() > 0 && PerInstancePrevTransform.Num() == GetInstanceCount();
When you add a single instance via AddInstance, the ISM will also add an element to PerInstancePrevTransform.
int32 UInstancedStaticMeshComponent::AddInstanceInternal(int32 InstanceIndex, FInstancedStaticMeshInstanceData* InNewInstanceData, const FTransform& InstanceTransform, bool bWorldSpace)
{
...
if (bHasPreviousTransforms)
{
PerInstancePrevTransform.Add(NewInstanceData->Transform);
}
However, when you add multiple instances via AddInstances, the ISM will not adjust PerInstancePrevTransform accordingly.
As a workaround, you can enable SetHasPerInstancePrevTransforms after the AddInstances call, but this is not a good solution when you need to add instances more than once. You can disable SetHasPerInstancePrevTransforms before the call and re-enable it after the call, but this will get expensive if there are a lot of existing instances. It will also likely break motion vectors for one frame.
This is how we fixed it in our project:
TArray<int32> UInstancedStaticMeshComponent::AddInstancesInternal(TConstArrayView<FTransform> InstanceTransforms, bool bShouldReturnIndices, bool bWorldSpace, bool bUpdateNavigation)
{
....
// CUSTOM CODE BEGIN
if (bHasPreviousTransforms && PerInstancePrevTransform.Num() < NumInstances) // the second condition is probably unnecessary
{
PerInstancePrevTransform.Reserve(NumInstances);
for (InstanceIndex = NumInstances - Count; InstanceIndex < NumInstances; ++InstanceIndex)
{
PerInstancePrevTransform.Add(PerInstanceSMData[InstanceIndex].Transform);
}
}
// CUSTOM CODE END
InvalidateCachedBounds();
return NewInstanceIndices;
}