UE5渲染

多线程模型

默认情况下,UE存在 Game Thread、Render Thread、RHI Thread,它们都独立地运行在专门的线程上(FRunnableThread)。

以场景中的一盏灯(ULightComponent)为例,它拥有完整的属性,可以被游戏逻辑随时修改(改变颜色、亮度)。

  1. 当灯光被创建或其属性发生变化时,游戏线程会创建一个 RenderProxy(如 FLightSceneProxy) 用于渲染线程使用。这个Proxy包含了渲染所需的数据(位置、颜色、强度等)的当前快照。
  2. 游戏线程将这个Proxy(或者更新命令)通过线程安全的命令列表(ENQUEUE_RENDER_COMMAND)发送给渲染线程。
  3. 渲染线程通常在下一帧使用这个Proxy进行渲染计算。渲染线程作为前端(frontend)产生的Command List是平台无关的,是抽象的图形API调用。
  4. 渲染线程将渲染命令添加到RHICommandList。RHI线程不断取出指令,向GPU发送,并阻塞等待结果。此时RHI线程虽然阻塞,但是渲染线程依然正常工作,可以继续处理向RHI命令列表 填充指令。RHI线程作为后端(backtend)会执行和转换渲染线程的Command List成为指定图形API的调用(称为Graphical Command),并提交到GPU执行。

这些线程处理的数据通常是不同帧的,譬如游戏线程处理N帧数据,渲染线程和RHI线程处理N-1帧数据:

但也存在例外,比如渲染线程和RHI线程运行很快,几乎不存在延迟,这种情况下,游戏线程处理N帧,而渲染线程可能处理N或N-1帧,RHI线程也可能在转换N或N-1帧。但是,渲染线程不能落后游戏线程一帧,否则游戏线程会卡住,直到渲染线程处理所有指令。

游戏线程和渲染线程代表

游戏线程的对象通常做逻辑更新,在内存中有一份持久的数据,为了避免游戏线程和渲染线程产生竞争条件,会在渲染线程额外存储一份内存拷贝,并且使用的是另外的类型,以下是UE比较常见的类型映射关系(游戏线程对象以U开头,渲染线程以F开头):

Game ThreadRendering Thread
UWorldFScene
UPrimitiveComponentFPrimitiveSceneProxy / FPrimitiveSceneInfo
-FSceneView / FViewInfo
ULocalPlayerFSceneViewState
ULightComponentFLightSceneProxy / FLightSceneInfo

游戏线程代表一般由游戏游戏线程操作,渲染线程代表主要由渲染线程操作。如果尝试跨线程操作数据,将会引发不可预料的结果,产生竞争条件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/** SceneProxy在注册进场景时,会在游戏线程中被构造和传递数据。 */
FStaticMeshSceneProxy::FStaticMeshSceneProxy(UStaticMeshComponent* InComponent):
    FPrimitiveSceneProxy(...),
    Owner(InComponent->GetOwner()) <======== 此处将AActor指针被缓存
    ...

    /** SceneProxy的DrawDynamicElements将被渲染器在渲染线程中调用 */
    void FStaticMeshSceneProxy::DrawDynamicElements(...)
    {
        if (Owner->AnyProperty) <========== 将会引发竞争条件!  游戏线程拥有AActorUObject的所有状态!!并且UObject对象可能被GC掉,此时再访问会引起程序崩溃!!
    }

部分代表比较特殊,如FPrimitiveSceneProxy、FLightSceneProxy ,这些场景代理本属于引擎模块,但又属于渲染线程专属对象,说明它们是连接游戏线程和渲染线程的桥梁,是线程间传递数据的工具人。

渲染一帧流程

  1. CPU第1帧开始,可见性剔除
  2. Early Z Pass(Depth only pass,和硬件的 Early Z 优化区分开),创建的第一个缓存区,叫“深度通道”,意味着我们可以在大多数材质的材质编辑器中访问场景深度
  3. Defer 渲染,生成 G Buffer,包括基础颜色、高光度、粗糙度、金属感,世界法线等等。这里如果场景中有静态光照,并且由Lightmass生成,那么这里还会用到因此创建的光照贴图
  4. 计算光照和阴影
  5. 雾和大气特效计算
  6. 半透明对象绘制
  7. 后处理

参考

https://zhuanlan.zhihu.com/p/546968578

https://zhuanlan.zhihu.com/p/1983913933166354972

https://zhuanlan.zhihu.com/p/21291425593

https://www.bilibili.com/video/BV1VT421a7vw

《大象无形》