UE Rendering
SViewport(UI), FViewport(RenderTarget), FViewportClient(Logic)
GameThread RenderingThread --Graphics API-> GPU
Engine Renderer, RHI,RenderCore, RHICore
UWorld UScene GPUScene
UPrimitiveComponent/Proxy PrimitiveSceneProxy/SceneInfo GetPrimitiveData(Parameters.PrimitiveID).xxxx
ULightComponent/Proxy LightSceneProxy/SceneInfo
FSceneView FSceneView,FViewInfo
注意:要时刻注意当前的代码是在游戏线程中执行,还是在渲染线程中执行
void UGameViewportClient::Draw(FViewport* InViewport, FCanvas* SceneCanvas)
// create the view family for rendering the world scene to the viewport's render target
FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
InViewport,
MyWorld->Scene,
EngineShowFlags)
.SetRealtimeUpdate(true));
FSceneView* View = LocalPlayer->CalcSceneView(&ViewFamily, ViewLocation, ViewRotation, InViewport, nullptr, PassType);
GetRendererModule().BeginRenderingViewFamily(SceneCanvas,&ViewFamily);
void FRendererModule::BeginRenderingViewFamily(FCanvas* Canvas, FSceneViewFamily* ViewFamily)
FScene* const Scene = ViewFamily->Scene->GetRenderScene();
if (Scene)
{
World = Scene->GetWorld();
if (World)
{
//guarantee that all render proxies are up to date before kicking off a BeginRenderViewFamily.
World->SendAllEndOfFrameUpdates();
}
}
// Construct the scene renderer. This copies the view family attributes into its own structures.
FSceneRenderer* SceneRenderer = FSceneRenderer::CreateSceneRenderer(ViewFamily, Canvas->GetHitProxyConsumer());
//通过任务队列的方式,向渲染线程发送任务,进行相关的渲染准备工作
ENQUEUE_RENDER_COMMAND(FDrawSceneCommand)( //向渲染线程队列发送命令,下面的代码逻辑由渲染线程负责执行;先发送的任务先被执行
[SceneRenderer, DrawSceneEnqueue](FRHICommandListImmediate& RHICmdList)
{
RenderViewFamily_RenderThread(RHICmdList, SceneRenderer);
FlushPendingDeleteRHIResources_RenderThread();
});
typedef TEnqueueUniqueRenderCommandType<TSTR, LAMBDA> EURCType;
TGraphTask<EURCType>::CreateTask().ConstructAndDispatchWhenReady(Forward<LAMBDA>(Lambda));
class TEnqueueUniqueRenderCommandType : public FRenderCommand
FRHICommandListImmediate& RHICmdList = GetImmediateCommandList_ForRenderCommand(); // FRHICommandListExecutor::GetImmediateCommandList(); ----> GRHICommandList.CommandListImmediate
Lambda(RHICmdList);