2
\$\begingroup\$

I have been reading up on data formatting for 3D objects so that I can render my meshes as fast as possible in OpenGL. I am quite new to OpenGL so bear with me.

The format for interleaving your meshes goes something like:

position, normal, texture1, texture2 //this I understand

Most formats for 3D meshes, however, don't use this structure. From my understanding the interleaved format is fast for execution but isn't necessarily the best in terms of size, since you never really have as many unique normals as you do vertices, since (if you are using hard shading) all normals for a face would be the same.

A hard shaded basic cube for example has 8 unique vertices and 6 unique normals.

So my question is, is it worth it to set up an interleaved format like this despite the fact that if you had 3 separate buffers you would use MUCH less data?

Also (remember I'm new) is it somehow possible to do pack your vertex information like:

all positions, all normals, all tex1, all tex2 //so all of one type in a sequence

and have different sets of indices for each type? Or is that just dumb?

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

Yes, interleaved is worth it.

Interleaved VBOs has no effect on the size of data. Even with separate VBOs for each attribute, you only have a single index buffer, so you need to duplicate any vertex attributes appropriately. That means that you have a single value of an attribute shared by multiple vertices, you must duplicate it for each vertex, no matter how you laid out your buffer objects. Yes, this means that some model formats require a lot of processing to put into a renderable format.

The GPU is generally much happier with a single interleaved buffer. Vertex processing happens by taking all the data for a single vertex and then running the shader. It's much faster to grab all that data in one go from a single memory location than to query multiple memory locations, due to how memory buses and caches work.

You could use a library like Open Asset Import Library to read your source format and then process it into a custom, efficient-to-render (for your engine) format and save that to disk as part of your content pipeline. You could also write a model software plugin that directly loads/saves the engine format, though this tends to be harder and you generally want the fully-featured native format around as your asset source (you almost certainly do want a plugin that can visualize the model in your renderer, though, so artists can see how things look while working on it and not being forced to guess or wait; iteration speed is king). Your engine then loads that efficient, processed file for rendering. Ideally your format is something you can copy directly into a vertex buffer and index buffer and whatever metadata structures you need (again, this is why this format is generally custom for an engine and not a general-purpose format).

You can pack multiple attribute streams into a single VBO end-to-end like you ask, though again it's still inefficient. The GPU must access multiple locations in the buffer for each vertex, which negatively impacts memory performance (same goes for CPU memory accesses). Interleaved is the way to go.

\$\endgroup\$
5
  • \$\begingroup\$ +1; view this as a tradeoff - you're exchanging increased memory usage for increased performance. It's worth noting that the only option that keeps the memory down is immediate mode, which you almost certainly don't want to consider. \$\endgroup\$ Commented Mar 24, 2013 at 21:00
  • 2
    \$\begingroup\$ -1: I want to see proof of this. This is a common belief, but I've never seen hard profiling data one way or the other. The pre-T&L cache should smooth out any multi-array accesses (more or less), so I don't really see how putting your arrays in multiple buffers would be a problem performance-wise. I'm not saying that you're wrong; it's just that, if we're going to answer this question, I would like to see evidence for it. \$\endgroup\$ Commented Mar 24, 2013 at 22:17
  • 2
    \$\begingroup\$ Fair enough. I should have clarified with my usual statement: never take performance claims at face value. Anything anyone says regarding performance (you, me, etc.) should be treated as nonsense until test on your specific app and specific hardware with real data. I personally don't feel it warrants -1 since my answer covered other things related to the question that have nothing to do with performance, like how you don't really save memory with multiple buffers and how shared attributes must be duplicated for each vertex in any layout. \$\endgroup\$ Commented Mar 25, 2013 at 1:06
  • 3
    \$\begingroup\$ "This is a common belief, but I've never seen hard profiling data one way or the other." then you also have not been reading every document that comes out of nVidia, AMD, and/or any medium/big game house. Please google harder. \$\endgroup\$
    – MickLH
    Commented Nov 29, 2013 at 19:04
  • 4
    \$\begingroup\$ Note that AMD is increasingly recommending non-interleaved buffers these days on newer GCN hardware. The times are a changin'. \$\endgroup\$ Commented May 7, 2016 at 0:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .