Hello, I am implementing a custom mesh drawer using a custom vertex factory and UMeshComponent in version 5.4.
The current problem is as follows:
After submitting a batch through UPrimitiveSceneProxy, rendering is failing due to PSO failure.
Below is the custom factory layout.
IMPLEMENT_TYPE_LAYOUT(FLocalVertexFactoryShaderParametersBase)
IMPLEMENT_TYPE_LAYOUT(FLocalVertexFactoryShaderParameters)
//
IMPLEMENT_VERTEX_FACTORY_PARAMETER_TYPE(FLocalVertexFactory, SF_Vertex, FLocalVertexFactoryShaderParametersBase);
IMPLEMENT_VERTEX_FACTORY_TYPE(FWorldVertexFactory, "/Engine/Private/LocalVertexFactory.ush",
EVertexFactoryFlags::UsedWithMaterials
| EVertexFactoryFlags::SupportsDynamicLighting
| EVertexFactoryFlags::SupportsStaticLighting
| EVertexFactoryFlags::SupportsPSOPrecaching
)
struct FVertexElemDef
{
FVector4f Position;
FPackedNormal TangentX;
FPackedNormal TangentZ;
FColor Color;
FVector2f TexCoords0;
};
void FWorldVertexFactory::InitRHI(FRHICommandListBase& RHICmdList)
{
//FLocalVertexFactory::InitRHI(RHICmdList);
check(IsInRenderingThread());
UE_LOG(LogTemp, Warning, TEXT("Factory InitRHI"));
uint32 Stride = sizeof(FVertexElemDef);
if (VertexBuffer == nullptr || !VertexBuffer->VertexBufferRHI.IsValid())
{
UE_LOG(LogTemp, Error, TEXT("VertexBuffer is invalid in VertexFactory::Init"));
return;
}
#ifdef POSITION_ONLY
FVertexDeclarationElementList decl;
decl.Add(FVertexElement(0, STRUCT_OFFSET(FVertexElemDef, Position), EVertexElementType::VET_Float3, 0, Stride));
FVertexStream VertexStream;
VertexStream.VertexBuffer = VertexBuffer;
VertexStream.Stride = Stride;
VertexStream.Offset = 0;
//FDataType Data;
Data.PositionComponent = FVertexStreamComponent(VertexStream.VertexBuffer, STRUCT_OFFSET(FVertexElemDef, Position), Stride, VET_Float3);
#else
FVertexStream VertexStream;
VertexStream.VertexBuffer = VertexBuffer;
VertexStream.Stride = Stride;
VertexStream.Offset = 0;
FDataType NewData;
NewData.PositionComponent = FVertexStreamComponent(VertexStream.VertexBuffer, STRUCT_OFFSET(FVertexElemDef, Position), Stride, VET_Float3);
NewData.TangentBasisComponents[0] = FVertexStreamComponent(VertexStream.VertexBuffer, STRUCT_OFFSET(FVertexElemDef, TangentX), Stride, VET_PackedNormal);
NewData.TangentBasisComponents[1] = FVertexStreamComponent(VertexStream.VertexBuffer, STRUCT_OFFSET(FVertexElemDef, TangentZ), Stride, VET_PackedNormal);
NewData.ColorComponent = FVertexStreamComponent(VertexStream.VertexBuffer, STRUCT_OFFSET(FVertexElemDef, Color), Stride, VET_Color);
NewData.TextureCoordinates.Add( FVertexStreamComponent(VertexStream.VertexBuffer, STRUCT_OFFSET(FVertexElemDef, TexCoords0), Stride, VET_Float2));
NewData.NumTexCoords = 1;
SetData(RHICmdList, NewData);
FVertexDeclarationElementList decl;
decl.Add(AccessStreamComponent(Data.PositionComponent, 0));
decl.Add(AccessStreamComponent(Data.TangentBasisComponents[0], 1));
decl.Add(AccessStreamComponent(Data.TangentBasisComponents[1], 2));
decl.Add(AccessStreamComponent(Data.ColorComponent, 3));
decl.Add(AccessStreamComponent(Data.TextureCoordinates[0], 4));
#endif // POSITION_ONLY
InitDeclaration(decl, EVertexInputStreamType::Default);
bInitialized = true;
}
bool FWorldVertexFactory::ShouldCompilePermutation(const FVertexFactoryShaderPermutationParameters& Parameters)
{
FLocalVertexFactory::ShouldCompilePermutation(Parameters);
return true;
}
void FWorldVertexFactory::ModifyCompilationEnvironment(const FVertexFactoryShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
FLocalVertexFactory::ModifyCompilationEnvironment(Parameters, OutEnvironment);
OutEnvironment.SetDefine(TEXT("MANUAL_VERTEX_FETCH"), 0);
}