- Data Load and Render Pass
- Load Static Mesh Render Data from Disk
- From CPU Memory to GPU Memory
- Position Vertex Buffer Example
- Loaded Data on GPU
- A Detail Look of the Vertex Buffer
Data Load and Render Pass
Strictly speaking, Data Load is not the execution content of the rendering pass.
However, as the data source for the rendering Pass, it is necessary to discuss this part before discussing the Pass execution process.
There are 2 design styles:
- Upload on demand: When rendering a Pass, if it is found that the data for a Mesh is not in the VRAM, the data for that Mesh is uploaded from memory to VRAM, and then the pointer is used for rendering.
- Upload on load: When loading a Mesh, the data is directly uploaded to the VRAM. Then, during rendering Pass, only the corresponding address in the previously uploaded VRAM is obtained to render that Mesh.
Unreal Engine has chosen the second style.
How is the Static Mesh data required for rendering loaded? We have already discussed this question in the previous section, but in this part, we will delve into the various details.
Load Static Mesh Render Data from Disk
Let’s take a look at this small arrow
How the unreal engine load the FStaticMeshRenderData
from the disk?
You can image the process as this:
FStaticMeshRenderData::Serialize
- For each
FStaticMeshLODResources
FStaticMeshLODResources::Serialize
- For each LOD section, load the section data
- Load the vertex and index buffer.
From CPU Memory to GPU Memory
After loading the data from disk, we need to transfer the necessary data into GPU memory,
To illustrate how initialization is mapped to the graphics API, let's consider the position vertex buffer as an example.
This may be helpful for someone who wants to check the source code themselves.
Position Vertex Buffer Example
Let's take PositionVertexBuffer
as an example.
The entire initialization process can be divided into two levels: the Renderer level and the RHI level.
The initialization process at the Renderer level involves calling the following functions in sequence:
- FPositionVertexBuffer
- FRenderResource
Once we enter the RHI level, it will ultimately map to specific rendering API calls, namely:
- RHICreateVertexBuffer
- FRHICommandListBase
- FD3D12DynamicRHI
From this level onwards, the mapped functions differ depending on the chosen API. If you, like me, are using DirectX12 RHI, then the next step would be to map to the creation of an FD3D12Buffer
.
Loaded Data on GPU
The Vertex Position data on the GPU appears to be like this:
The index buffer on the GPU appears as follows:
The final appearance of our Cube looks like this:
A Detail Look of the Vertex Buffer
Readers may be interested in the specific properties of this Buffer.
- Stride: 12 bytes. Each element is a vertex coordinate, consisting of 3 float coordinates, which is 3 x 4 = 12 bytes.
- Element Count: Note that our Cube consists of 6 faces, with each face containing 9 vertices. Therefore, the total number of vertices is 9 x 6 = 54.
This is because the normal direction of two vertices at the same position on the same edge is different. Therefore, they are split into 2 vertices. If you are familiar with the "smoothing groups" feature in 3D Max or other DCC software, these edges are considered "hard edges" here.