Hello,
We are working on a custom mesh rendering pass for our game.
It is based on a FMeshPassProcessor without any engine modification (game module).
Meshes are registered in a world subsystem, with their bRenderInMainPass property disabled. They are not using Nanite. A scene view extension handles creating the FMeshPassProcessor instance (in PostRenderBasePassDeferred_RenderThread), looping over all registered mesh proxies within a AddSimpleMeshPass call (see code at the bottom).
When in-game (PIE), and switching to Wireframe view with F1, an ensure is raised (FRHIPassInfo::Validate) :
// Ensure NumSamples matches with color RT
if (NumSamples != -1)
{
ensure(DepthStencilRenderTarget.DepthStencilTarget->GetNumSamples() == NumSamples);
}
Here, NumSamples is 4 in Wireframe view while the D/S attachment only has 1 sample, triggering the condition. After the ensure, the GPU device hangs, crashing the game. As a side note, switching to Eject mode (F8), and then manually selecting the Wireframe viewmode from the dropdown doesn’t trigger this condition.aa
How could we make our FTransparencyMeshPassProcessor compatible with wireframe, or at least disable it in order to avoid crashing ?
We have already tried detecting the viewmode inside the SVE’s IsActiveThisFrame_Internal method, but the crash happens right at the frame when pressing F1, where the previous draw command is already in flight.
if (GIsEditor && GEditor)
{
for (FLevelEditorViewportClient *const LevelVC : GEditor->GetLevelViewportClients())
{
if (LevelVC->Viewport == Context.Viewport)
{
if (!LevelVC->IsViewModeEnabled(EViewModeIndex::VMI_Lit))
{
return false;
}
}
}
...
Thanks in advance,
Tim
---------------
Drawing code within the Scene View Extension’s PostRenderBasePassDeferred_RenderThread :
AddSimpleMeshPass(GraphBuilder, PassParameters, InView.Family->Scene->GetRenderScene(), InView, nullptr, RDG_EVENT_NAME("Transparency %dx%d - %u prims", RTSize.X, RTSize.Y, RegisteredPassPrimitives.Num()), static_cast<const FViewInfo&>(View).ViewRect,
[&InView, this](FDynamicPassMeshDrawListContext* DynamicMeshPassContext)
{
FTransparencyMeshPassProcessor Processor(InView.Family->Scene->GetRenderScene(), &InView, DynamicMeshPassContext);
Processor.SetOpacity(FMath::Sin(GFrameCounter * 0.25f) * 0.5f + 0.5f);
for (const FPrimitiveSceneProxy *const Primitive : RegisteredPassPrimitives)
{
if (Primitive == nullptr)
{
return;
}
TArray<FMeshBatch> MeshElements;
Primitive->GetMeshDescription(0, MeshElements);
if (MeshElements.IsEmpty())
{
continue;
}
for (const FMeshBatch& Batch : MeshElements)
{
Processor.AddMeshBatch(Batch, ~0ull, Primitive);
}
}
});