5
\$\begingroup\$

I'm writing an DirectX11 game.

About 60% of my game models (or "of my vertices") have:

  1. Position
  2. Texture coordinate

Some of them use:

  1. Position
  2. Texture coordinate
  3. Normals

And few of them:

  1. Position
  2. Texture coordinate
  3. Normals
  4. Tangents
  5. BiTangents

And I have about 10 shaders:

  • 3 of them assume that vertices have just position and texture coordinates
  • 5 that they also have normals
  • 2 make use of tangent/bi-tangent info

The question is: should I create 3 vertex structures and 3 D3D11_INPUT_ELEMENT_DESC arrays for them (option 1)? Or create only one, universal vertex structure (the last one, 5 members) and 1 D3D11_INPUT_ELEMENT_DESC for it (option 2)?

What I see:

Option 1:

  • No unused data will be transfered to shader - e.g. 60% of models will be rendered with simple shader that don't calculate normal maps and we will send to him just position/texture coordinate.

Option 2:

  • Only one input structure, no need to switch vertices types - simpler code, maybe faster (no switching)?, no need to bother if new shader needs 1st, second or third structure (we can just pass everything to it and it will decide which members to use).
\$\endgroup\$
  • \$\begingroup\$ My intuition says option 1, I don't think switching between vertex formats is expensive enough to justify the extra bandwidth required by option 2. And batching things using the same vertex format together can alleviate the issue if it ever happens. But I've no hard data to back this up. \$\endgroup\$ – Laurent Couvidou May 9 '14 at 13:45
2
\$\begingroup\$

I would say that you should try to keep the size of your data (vertex buffers, arrays) at the minimum, especially if you want to be updating the vertex buffers since that is a slow operation even if you created them with dynamic usage flag. More data will slow down that operation significantly. Also I don't know what big of a program you are developing but wasting space is usually a big luxury. :)

And since you already have different types of shaders for different layouts I see no need to keep empty data in several of your models. I would recommend however to avoid switching layouts and shaders when unnecessary. For this you could draw everything which uses the first layout first, then draw everything which uses the second layout and so on.

\$\endgroup\$
2
\$\begingroup\$

János Turánszki is correct. That's quite a luxury to waste memory in any serious game. The memory spaces occupied by the vertices is not the only / major problem. The GPU performance suffers from loading unnecessary data from vertex buffers. That trashes the vertex cache, and bring extra workload to the input assembler. It's always a good practice to keep the data size minimized.

Switching rendering contexts too many is a different problem. If you have many combination of shaders / input layouts / vertex buffers / etc., it would generate a lot of draw calls to waste the driver. However, since you just have around 10 shaders, that might not be an issue to your game. Even low-end PC could easily generates more than 1,000 draw calls per frame. If you combine your vertex buffers and sorting the shaders properly, you should be completely safe.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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