A crash can occur due to this check in Substrate.cpp when a material with 2 units and a material with 5 (20 bpp) uints are combined triggering :
check(CurrentMaxBytesPerPixel <= PlatformSettingsBytesPerPixel);
This can happen with Niagara vfx that has two or more emitters whose materials compile to Substrate uint counts that bitwise OR above the maximum, with blendable Substrate enabled and r.Substrate.ProjectGBufferFormat=0. The base class FMaterialRelevance operator|= function applies Max() to SubstrateUintPerPixel but the derived class FPrimitiveViewRelevance operator|= does not. When a material with 2 units and a material with 5 (20 bpp) uints are combined with | it results in 7 (28 bpp) which triggers the check(). A potential workaround is to add the missing Max():
/** Bitwise OR operator. Sets any relevance bits which are present in either. */
FPrimitiveViewRelevance& operator|=(const FPrimitiveViewRelevance& B)
{
const uint32 LocalSubstrateUintPerPixel = SubstrateUintPerPixel;
// the class is only storing bits, the following avoids code redundancy
const uint8 * RESTRICT s = (const uint8*)&B;
uint8 * RESTRICT d = (uint8*)this;
for(uint32 i = 0; i < sizeof(*this); ++i)
{
*d = *d | *s;
++s;++d;
}
SubstrateUintPerPixel = FMath::Max(LocalSubstrateUintPerPixel, B.SubstrateUintPerPixel);
return *this;
}
Expected
The Emitter renders without crashing
Actual
The Editor crashes
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-400816 in the post.