Render Proxy

Cube, but in the renderer’s eyes

Now, let's start digging in.

From Gameplay World to Renderer World

The renderer doesn't care about the gameplay classes.

Gameplay
Render
Player Enemy HP Jump Attack
Skeletal Mesh Static Mesh Particle

It doesn't need to know how fast your player can move or what the HP is.

Its only concern is what needs to be rendered: a mesh, a particle, or a sprite.

Update and Sync between two Worlds

image

This image, from Design Patterns for Low-Level Real-Time Rendering, is a really good explaination of the architecture.

  • The idea is that the game thread updates the gameplay logic, mostly through tick functions.
  • Then, it captures the render-related information into FRenderProxy and sends it to the render thread.

An example:

image
  1. Game world tick: our cube moved 3 cm forward
  2. Capture: after the tick, we send this information to the FRenderProxy, by updating its transform info
  3. Render thread update: since we need to render this frame, the render thread will update the new transform info to the GPU memory and ask GPU to render the cube based on the new transform info.
  4. The cube appears at the new location, 3cm away from the last location
  5. Our brain tell us, the cube has moved

Render Proxy Layer

Let’s add the RenderProxy layer to our mindmap.

image

So now the story becomes:

  • The game thread updates the actors and components
  • After that, the game thread gets the FStaticMeshSceneProxy from our cube static mesh component
  • The game thread ask render thread to start rendering this frame.
  • The render thread takes the rendering data, both the runtime data (render proxies from components) and the common data (render datas from assets), and render the image.

Question for Next Step

However, we are still far from the actual rendering instructions (i.e., rendering API calls).

  1. A Render Proxy may have multiple Materials, but a rendering request (i.e., Draw Call) can only have one set of Shaders.
  2. A Render Proxy may be rendered in multiple stages: GBuffer, shadows, etc., and we need to divide it into multiple Draw Calls.

We will focus on how a Render Proxy is transformed into rendering instructions.