1
\$\begingroup\$

I am working on a rendering problem where I want to render as many raw triangles to the screen as I can with either OpenGL or DirectX with the absolute fastest performance possible.

I wondered about omitting vertex normals completely and only transforming vertex positions during the vertex shader stage.

1) Is this possible?

2) Is it actually going to increase performance --or-- is the "bare metal" of the GPU designed in such a way that trying to omit normals won't gain any more throughput?

p.s. Yes, I realize that omitting normals will leave you with the problem of how to shade the triangle during the shader stage, but I could at least render a solid color to the screen (no shading). At this point, all I'm wondering about is how much data I can eliminate from the typical pipeline to increase the pipeline throughput to the absolute maximum.

\$\endgroup\$
  • \$\begingroup\$ You would be transferring less data to GPU memory, so it would be faster in that respect yes. I'm not sure how the GPU shares values stored in registers between stages, but I suspect if the values aren't being used it would be optimized in such a way to not make a difference. I would say the biggest performance gain would be from less data being transferred. \$\endgroup\$ – Evan Nov 21 '13 at 19:21
4
\$\begingroup\$

Yes, it is possible. When you configure your input layout (in D3D10+) or vertex attributes (OpenGL), simply only include the position. Don't configure any additional data such as normal or texture coordinates.

Then, when you fill your vertex buffers, you only need to fill them with position data. Perform your fixed coloring in the fragment shader.

This will be slightly faster, because your vertex shader doesn't need to transform or handle the extra data at all. You also won't need to copy as much data from the CPU to the GPU when you define the buffers. Will it be appreciably faster? I'd guess no, but if you're pushing as much data as possible, then maybe. You'd have to profile it and see.

\$\endgroup\$
  • 1
    \$\begingroup\$ +1 I totally agree with the profile your application approach. and probably will be small difference. \$\endgroup\$ – concept3d Nov 22 '13 at 0:26
  • \$\begingroup\$ My intention is to push as much vertex data as absolutely possible. I'm definitely going to make the performance vertex-limited. I appreciate your answer on this. Thanks! \$\endgroup\$ – JamesHoux Dec 5 '13 at 18:15
2
\$\begingroup\$

You're unlikely to be bus-limited or vertex-limited on current or even recent hardware; except in extreme and unlikely scenarios, fillrate and ROP will kick in a lot sooner.

If omitting normals gets your vertex size below 32 bytes that can be a win. If you still need some kind of shading, you can get normals down to 4 bytes (instead of 3 floats) by using a signed/normalized vertex format, and it will look sort of OK.

But if drawing the maximum number of triangles possible is your goal, you'll get much more mileage from batching draw calls, and shifting CPU-side calculations to the GPU (even if it means doing some of them per-vertex rather than per-triangle, i.e. a 3x increase) so as to allow you to keep your vertex data in static buffer objects.

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

The performance difference will depend a lot on the hardware you're using, the only way to be sure is to test it.

Technically you don't need a vertex buffer or index buffer at all - you can generate the position in the vertex shader in DX10/11, based on the integer index of the vertex.

You can of course also skip the transform, by passing coordinates through in clip space.

\$\endgroup\$
  • \$\begingroup\$ +1 for mentioning that you don't need buffers at all to draw. \$\endgroup\$ – Maximus Minimus Nov 22 '13 at 15:39

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.