本文档详细梳理了UE5的渲染流水线,从游戏线程(Game Thread)到渲染线程(Render Thread)再到RHI执行的全过程。每个模块首先说明设计目的和功能目标,然后介绍相关实现细节,并列出关键源码类、函数和文件。
游戏线程:渲染对象的组织
目标: 在游戏线程上管理和维护所有可渲染的物体(Primitive),并为它们创建在渲染线程上使用的代理(Scene Proxy)。游戏线程负责组件状态管理、场景注册以及将必要的数据拷贝到渲染线程可访问的线程安全结构中。
在UE中,任何可渲染物体都是继承自 UPrimitiveComponent 的组件,比如 UStaticMeshComponent、USkinnedMeshComponent、UInstancedStaticMeshComponent 等。这些组件在被激活(Register)后,会调用其 CreateSceneProxy() 方法创建一个对应的渲染线程代理。该代理的基类为 FPrimitiveSceneProxy,它是游戏线程组件在渲染线程中的“镜像”表示。例如,UStaticMeshComponent::CreateSceneProxy() 返回一个 FStaticMeshSceneProxy(StaticMeshSceneProxy.h/cpp)实例;USkinnedMeshComponent::CreateSceneProxy() 返回 FSkeletalMeshSceneProxy。每个代理会将组件的几何数据、变换、材质相关信息等缓存在自身字段中,以便渲染线程使用。
创建好的场景代理并不会立即进行渲染,而是被包装在FPrimitiveSceneInfo对象中,该对象封装了组件和其代理的状态,并由全局 FScene(Scene.cpp)管理。FScene内部通常维护了一个加速结构(如八叉树)以进行视锥裁剪和碰撞检测。所有激活的可渲染组件在注册时会调用 FScene::AddPrimitive()(位于 Scene.cpp),从而将对应的 FPrimitiveSceneInfo 加入场景。这样,渲染线程在后续帧中就能访问到这些代理和相关数据。简而言之,游戏线程负责定义游戏世界的几何和材质状态,通过 FPrimitiveSceneProxy 和 FScene/FPrimitiveSceneInfo 将其安全地传递给渲染线程。
关键类与文件: UPrimitiveComponent及其派生类(UStaticMeshComponent、USkinnedMeshComponent 等);它们的 CreateSceneProxy() 实现位于 StaticMeshRender.cpp、SkinnedMeshComponent.cpp 等文件中(见文档)。在渲染模块内,FPrimitiveSceneProxy(及其子类如 FStaticMeshSceneProxy、FSkeletalMeshSceneProxy,对应头文件 StaticMeshSceneProxy.h、SkeletalMeshSceneProxy.h)、FPrimitiveSceneInfo(位于渲染模块,源码在 SceneRendering.cpp 或相关文件)和 FScene(Scene.h/cpp)等是核心结构。