[toc]
# 开篇
虚幻引擎那么厉害的画面,是通过什么样的过程产生的呢? 首先,渲染系统的线程和游戏逻辑的线程是分开的,其次,渲染线程对图像的生成依赖于逻辑线程的 drawCall (提交)。
所以可以认为渲染引擎是附庸于游戏逻辑而存在的。
源码是 4.6
# 1. 获取渲染线程
PreInitPostStartupScreen -> RendringThread.StartRenderingThread() -> FRHIThread::Get().Start();
# FRHIThread (仅用在内部中)
这个类继承自 FRunnable
,Runnable 这个词常用于多线程的环境下,如 Java 中,一个新的自定义线程会封装成一个 Runnable
, 这个也类似。 即 UE 中新的线程需要继承 FRunnable 另外,FRHIThread 实际上是 FRunnableThread
封装一层后的类。实际的渲染线程逻辑是在 FRunnableThread
中,而 FRHIThread
在这个版本中只负责了启动以及 获取渲染线程Runnable的全局唯一单例
如 Get
方法
1 | static FRHIThread& Get() |
获取单例之后就可以开启渲染线程了,表层代码如下:
1 | void Start() |
可以看到,实际渲染线程的 Create
发生在这个函数中。 渲染线程的启动是发生在其创建之后,创建完成的渲染线程会经过 UE 的 TaskGraph
创建一个新的线程 Task
来执行其本身的逻辑。这段代码同样发生在 StartRenderingThread()
函数中。
# GRenderingThreadRunnable - FRenderingThread (非内部全局渲染线程)
如上所述,实际的渲染线程的逻辑包装在 FRenderingThread
中。
在渲染线程启动时,会在全局渲染线程对象指针 GRenderingThreadRunnable
上创建一个新的 FRenderingThread
这段代码同样在 StartRenderingThread()
函数中。其主要流程如下
- 1. Create 创建渲染线程,并赋值给全局指针 - 2. 等待渲染线程创建好,从自己的 TaskGraph
中取出任务并执行。 - 3. 根据线程 ID 注册该渲染线程
- 4. 开启 FRenderingThreadTickHeartbeat
,即心跳更新渲染线程