Quick question on data transfer

As a 3d vertex, I have the following structure:

float s, t;
float r, g, b, a;

VECTOR3D position; // each VECTOR3D contains 3 floats
VECTOR3D normal;
VECTOR3D sTangent;
VECTOR3D tTangent;

Assuming sizeof(float) = 4 bytes, we have 72 bytes(!!!) per vertex.

The question(s) are:

  1. Does ill-alignment of TANGENT_VERTEX affect performance of an OpenGL application?

  2. Size of TANGENT_VERTEX can be made 64 bytes by making (r, g, b, a) components not floats, but unsigned short’s. But shall I gain any perf. boost by this?

Actually i think you could reduce it to:

struct MyVertex
VECTOR3D position;
VECTOR3D normal;
VECTOR3D tangent;
unsigned char rgba;

The 4 unsigned bytes color is a standard format for colors; but are you sure this is even needed ? It looks like a vertex format to do bump-mapping, in which case the color is determined per pixel by the color of the light, the diffuse texture, and the per-pixel shading (dot3 between normal map and vertex-to-light vector).

The binormal can be removed from the vertex format, and calculated in a vertex program.

That’d be 48 bytes per vertex, much better.

You will only gain performance if you’re bandwidth limited, so your scene must be quite complex and vertices dynamically filled. If storing your vertices in video memory (like through VBO), it will likely not be a performance win, but might help reducing the memory usage (always a good thing).

I don’t think you’ll see performance problems with ill-alignments like 72, but aligning on 16 or 32 bytes couldn’t hurt.


I second the recommendation to use unsigned char[4] for the color, if you need the color at all.

I also second the recommendation to reconstruct the third vector using cross product, unless you support mirroring of the tangent basis (which may or may not be a great idea). For mirroring, you could use the w component of the binormal as a scaler (1 or -1) to avoid bloating the vertex too much.

If size is really a concern, using SHORT for normals and tangent-type vectors saves space, but you have to align the start of each group on 4 bytes for NVIDIA hardware (dunno about others). You could use shorts for texture coordinates too. And even position. Shorts are typically reasonably well supported on current and near-past hardware.