From Render Data to Shader Inputs

How do we load the cube’s vertex data from disk, and transfer to GPU, finally used in vertex shaders?

Data Structure of the UStatic Mesh

Unreal engine loads the cube’s vertex data from the disk, inside UStaticMesh ’s serialization function. And transfer the result into FStaticMeshRenderData .

The render data contains different Levels of Detail (LOD) in the FStaticMeshLODResources, which hold the vertex buffers and index buffer(s). Additionally, it contains a reference to the VertexFactory. If you forget, here is the explaination of that.

These buffers do not need to be changed during runtime and can be directly stored in the GPU memory. We can envision the process as follows:

image

We used a ambiguous description for the vertex buffer’s number. Because we will talk about the details here.

Vertex Streams

Unreal splits the vertex information into different streams. For instance, 'FPositionVertexBuffer' holds position-only data, while the StaticMeshVertexBuffer contains TangentsData and TexcoordData.

As a short background info:

image

In the realm of rendering programming, there are two primary ways to organize vertex data: Array-of-Structures (AoS) and Structure-of-Arrays (SoA).

The Array-of-Structures (AoS) style is akin to a tightly packed suitcase, where all the data associated with a vertex (like position, color, texture coordinates, etc.) are stored together in a single stream. This is like packing all the items for a single day (shirt, pants, socks, etc.) together in a suitcase. It's convenient when you need all the data at once, but it can be inefficient if you only need a specific piece of data for all vertices, like just the positions.

On the other hand, the Structure-of-Arrays (SoA) style is more like a well-organized closet, where different types of data are stored in separate streams. It's like having separate drawers for shirts, pants, and socks. This can be more efficient when performing operations on a single type of data for all vertices, like transforming all positions, but it can be less convenient when you need all the data for a single vertex.

Requirement of the Data is Changing

In Unreal Engine, the number of attributes needed depends on the pass.

For example, the Depth Prepass does not require the vertex color attribute.

Therefore, Unreal Engine organizes the data in the Structure of Arrays (SoA) style.

Let’s look back to our cube. In the vertex shader from Depth Prepass, our cube loads the following data:

image

Abviously this is the vertex positions in the cube’s local space.

Summary

Finally, let’s add what we found to the summary image:

image
ℹ️
Again, this is just a roughly mind map. We skipped a lot of details. But we will cover the details later.