Graphical UE4 rendering system Part 1 multithreaded rendering


Last replyPart 0 engine basicsSpeaking of, we know roughly what classes UE4 uses to manage the data in a game scene, but this is only a small step for us to explore the UE4 rendering system.

This section mainly introduces the part of the macro top layer in UE4 rendering system——Multithread Render , the specific multithreading is divided into:

  • Game thread(GameThread)
  • Rendering thread(RenderThread)
  • RHI thread(Render Hardware Interface Thread)


Why multithreading?


The most basic theory used to describe “rendering” is that, as shown in the figure, the CPU invokes the drawcall command (also known as drawing instruction) provided by the graphics API to explain the data, attributes, etc. to be rendered in the command, and then the CPU waits for the GPU to return the rendering result to complete the rendering. For those scenes with low rendering frequency, there is no problem with this method, but in the high-frequency scenes that need real-time rendering, the problem appears.

In addition to submitting drawcall, the CPU spends a lot of time on processing game logic operations and preparing rendering data, such as processing user input, executing game scripts, updating physics and animation, visibility culling, etc.


If the engine leaves everything to the gamethread to complete, when the gamethread has finished what should be done in the current frame and is ready to render the data and submit it to the GPU, the gamethread can only wait for the rendering result, but after the gamethread receives the user input of the current frame, it can fully perform various tasks of the next frame, but the single thread mechanism does not allow such things.

Multi core CPU and multi-threaded concurrent and parallel operating system are not uncommon today. It is natural to separate rendering related tasks from gamethread, let gamethread focus on various computing tasks in game logic, and let renderthread and GPU complete rendering tasks.


After adding renderthread, each time gamethread processes various tasks, prepares rendering data, sends the data to renderthread, and then continues to process the task of the next frame. Renderthread receives the data, performs some data processing (such as visibility culling), submits drawcall to GPU, waits for rendering results, and completes rendering.

What is rhithread? There may be many reasons for the proposal of RHI in UE4:

  • Support multiple graphics APIs across platforms
  • Submit drawcall in parallel
  • Various other performance optimizations

The first is for a variety of cross platform graphics APIs. Due to the different graphics APIs supported by different platforms, Direct3D limited by windows, metal limited by MacOS, OpenGL and Vulkan limited by cross platform (including mobile terminal). Before rhithread, renderthread will select drawcall according to different graphics APIs, which will certainly increase a lot of workload and complicated maintenance.

“All problems in computer science can be solved by another level of indirection.” —— Jay Black

Wouldn’t it be nice to leave it to a single thread? No, rhithread is coming.


After the renderthread prepares the rendering data, it submits a rhidrawcommand irrelevant to the graphics API to rhithread. Rhithread pulls out a table to find out which sentence in the graphics API of the current platform is the corresponding drawcall, and then submits the drawcall to GPU to wait for the rendering result and complete the rendering. In this way, renderthread can focus on its own tasks (convenient for optimization) and complete the iterative maintenance of graphics API versions of various platforms on rhithread.


Of course, this is the reason why rhithread exists from the perspective of engineering optimization. Of course, RHI has some more direct reasons, that is, to support parallelization and submit drawcall. In some older graphical APIs, drawcall is blocked, that is, when a thread submits a drawcall, other threads are not allowed to submit it. After the graphics API calls GPU for calculation, the calculation and rendering of GPU itself takes time. In this time, if the graphics API can prepare for the next drawcall, it must be better.


With the technology update, some new graphics APIs begin to provide some parallelized ways to submit drawcall. When there is no RHI, can UE4 run multiple renderthread? It doesn’t seem reasonable. Except for submitting drawcall, other parts of renderthread don’t need multiple threads to complete. The multithreaded task that needs to be proposed separately naturally becomes rhithread.


It can be seen that the design of multi-threaded rendering in UE4 rendering system is not like this at the beginning, but is developing and improving with the needs of Technology (it is estimated that many changes have been made in the new ue5).

This time, we didn’t focus on the tasks of various internal details of threads, nor did we explain in depth how each thread transmits specific commands and data, because it’s too long to talk about. Then we’ll sort it out slowly. There are a lot of materials on the network. You can expand your reading by yourself.


Recommended Today

On the kernel of time series database: how to carry 100 million data writing with a single machine

This article was first published inDevelopment paper: edition date remarks 1.0 2021.10.19 Article launch 1.0 2021.11.21 Supplement the content added when sharing in the company 0. Background The title comes from the background introduction of the birth of their storage engine by influxdb: The workload of time series data is quite different from normal database […]