更新
A much better answer has been posted on Unreal Answers by Rama:
使用AActor::GetLastRenderTime() 找出每个actor 的最后绘制时间,或使用UPrimitiveComponent::LastRenderTime 找出基元本身。他的回答解释了如何使用它。
原答案:
正如您所建议的,当 Unreal 必须检查以进行剔除时,您必须对碰撞体积做一些事情似乎很奇怪,因此我找到了以下方法来查询该信息:
首先我们必须从相机创建一个FSceneView。 This code is taken from the UE Answers question.
APlayerCameraManager* Manager = World->GetFirstPlayerController()->PlayerCameraManager;
ULocalPlayer* LocalPlayer = World->GetFirstLocalPlayerFromController();
FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
LocalPlayer->ViewportClient->Viewport,
World->Scene,
LocalPlayer->ViewportClient->EngineShowFlags)
.SetRealtimeUpdate(true));
FVector ViewLocation;
FRotator ViewRotation;
FSceneView* SceneView = LocalPlayer->CalcSceneView(&ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport);
一旦我们创建了视图,我们就可以遍历所有原始组件(包括网格),然后我们可以使用静态网格的SceneProxy 的边界和视图的边界进行我们自己的剔除。
for (TObjectIterator<UPrimitiveComponent> ScenePrimitsItr; ScenePrimitsItr; ++ScenePrimitsItr)
{
// Using the Object iterator so we have to skip objects not in the
// relevant world
if (ScenePrimitsItr->GetWorld() == World)
{
FPrimitiveSceneProxy* Proxy = ScenePrimitsItr->SceneProxy;
if (Proxy)
{
bool bIsShown =
SceneView->ViewFrustum.IntersectSphere(Proxy->GetBounds().Origin, Proxy->GetBounds().SphereRadius)||
SceneView->ViewFrustum.IntersectBox(Proxy->GetBounds().Origin, Proxy->GetBounds().BoxExtent);
}
}
}
截锥体检查来自方法FrustumCull 中的SceneVisibility.cpp 此方法并不理想,因为a) 涉及复制该检查并且b) 执行两次测试。但是,我找不到实际查询结果的方法。它似乎存储在FViewInfo 的位数组中。不幸的是,这个信息没有暴露在渲染器模块之外。