2
$\begingroup$

A typical definition of a Vertex structure in C++ might look something like this:

struct Vertex
{
    Vec3 pos;
    Vec3 color;
}

However, we found ourselves designing a multi-purpose system where sometimes we need textures, sometimes colors, sometimes normals etc. and sometimes even all 3.

How is this usually delt with in graphics programming, where a single system might need to make use of different types of vertex structures?

I see two main options:

  1. Define a single vertex structure with all the attributes defined and only used those that are need for each scenario. The disadvantage for this seems to be the memory usage on both the CPU and GPU side for storing thse structure
  2. Define multiple different structures with different attributes. The disadvantage for this might be that it could become a management nightmare.

Thoughts?

$\endgroup$

1 Answer 1

3
$\begingroup$

Most rendering engines do need to handle multiple vertex structures depending on the type of shading being used on the mesh.

If there are only a small number of discrete vertex structures, you could simply create an enum to list them and define a struct for each one. However, many rendering engines take a fully data-driven approach to it, where there is no predefined vertex structure, but just a buffer of raw bytes plus a metadata description that lists the offset and type of each vertex component within the structure. It creates a lot of extra housekeeping code, but it is the most flexible way to deal with vertex structures.

An alternate approach is to use "deinterleaved" vertices, where each vertex component is in its own array. You'd have one array of positions, one array of colors, one array of normals, etc. This allows for components to be present or absent simply by populating that array or leaving it empty. The GPU can read deinterleaved vertex data as well as interleaved data; you just have to configure the vertex arrays appropriately. Deinterleaved vertices may be less efficient overall, as more memory transactions are required to read the data this way. On the other hand, that may not matter much if the GPU is not vertex-bound on your scene.

An advantage of the deinterleaved approach is that sometimes different vertex components are relevant for different rendering passes on the same mesh; for example, shadow rendering usually only needs positions and not colors. Deinterleaved vertex data makes it easy to supply only those components that are relevant for the current pass, so the GPU need not spend extra bandwidth reading irrelevant data.

A middle ground is to partially deinterleave the data, so that positions are in one array and all the other components are interleaved together in another array, for example (or any other combination you choose).

$\endgroup$
1
  • $\begingroup$ The fully data driven approach is a pain to set up, but worth the extra effort. Once its up and working suddenly all kinds of new possibilities emerge which makes it easier to grow and change a flexible system. Deinterleaved data tends to hurt cache performance which tends to negate the entire reason for deinterleaving in the first place but is a handy development tool for performance sensitive applications. $\endgroup$
    – pmw1234
    Jul 28, 2021 at 19:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.