multiple indices for different array (vertex, color,...)

Hi,

Maybe my question is really stupid but after a full day reading all the vertex_xxx extension specification, I dare ask it.

In my program I have an array containing the vertex, and an other containing the color. But the color of the i_th vertex in the vertex array is not in the i_th color of the color array (I share the vertices but not the color).
Is there a way I can render my scene using those two arrays with 2 indices arrays (one for the vertex and an other for the color)?

Thanks a lot for your help

Rhett

Immediate mode is the only way. If you use vertex arrays, the same index is used for all arrays. So if a vertex shares some attributes but not all, all it’s attributes must be duplicated.

You need to normalize your arrays .

The multiple indices per mesh will be a feature in … WGF (DirectX 10)

If you need something faster than what jwatte suggested (doing it that way gets extremely slow if your model is large) you can use a simple hash-table to quickly check whether an identical pair of indices have been passed in before. It takes the time down to near linear if the hash-table is large enough.

Originally posted by execom_rt:
The multiple indices per mesh will be a feature in … WGF (DirectX 10)
Err…why?
How would that affect the vertex cache?

How would that affect the vertex cache?
Which one? Pre-T&L or post-T&L?

For pre-T&L, it is meaningless. If it can fetch from multiple locations of memory using one index, then it isn’t so difficult to see it fetch from multiple locations using multiple indices.

As for the post-T&L cache, well, it would only use the post-T&L entries if all the indices are the same. Simple.

It only adds to the cache if all indices are the same, and only searches the cache if all indices are the same?
Right…so who in their right mind would use multiple index arrays?
If nobody’s going to use them because of the performance impact (ie zero cache usage) then why bother introducing them into the API?

It’s useful if you don’t want to waste memory.
You might be able to save on 32 bit color per vertex or 64 bit tex coords (u, v) and replace it with unsigned short.

>>>For pre-T&L, it is meaningless. If it can fetch from multiple locations of memory using one index, then it isn’t so difficult to see it fetch from multiple locations using multiple indices.<<<

I think it will effect cache performance.

It only adds to the cache if all indices are the same, and only searches the cache if all indices are the same?
No, I didn’t say that. Or I mis-wrote.

The way a post-T&L cache now works is that it stores some number of entries. The key for these entries is the index that was used to provoke them. As such, the only time post-T&L cache data is used (rather than T&L’ing the vertex) is if the incoming vertex’s index matches one in the post-T&L cache.

Now, if you have multiple indices, then the sequence of indices becomes the key. The only time the post-T&L cache data is used in this case is if the sequence of indices for the incoming vertex matches the sequence of indices for the cache entries in the post-T&L cache.

It would seem, without putting any thought into it, that the likelihood of these matching is more remote than in the single-index case. However, that’s if you assume a random indexing scheme.

Take the typical “box” case, where you have 8 positions, but 24 texture cooridinates. If you use a single-index system, you have 24 vertices; that’s 24 separate indices. When you render these as individual triangles (a list), you get some matching, but only for the 2 triangles that make up a face.

If you use 2 sets of indices, you match at the same times as you did for the single indexed case. You repeat sets of indices at the same places as the single index case. All the multiple index case does is slightly complicate the post-T&L logic and potentially buy you back some memory.

I think it will effect cache performance.
In what way? The pre-T&L cache must already be able to fetch from disperate locations in memory, since we are allowed to have different vertex attributes in different VBO’s. All the multiple indexing would add is the ability to use a different index for each base pointer. It means that you have to dereference multiple indices into the memory pointers, but the accessing logic is no different than before.

It’s useful if you don’t want to waste memory.

We did extensive measurements on real-world meshes, and for all but the lowest-poly real-world meshes, a single index list and normalized vertices was smaller than multiple indices.

I e, while separate indices is a win for things with lots of seams, like a cube (where every vertex is a seam); most real geometry has a low seam to continuous vertex ratio, and thus the single-index array plus single index array is smaller than the multiple arrays plus multiple index arrays. It’s the size of the multiple index arrays that kills you!

So in the general case most indices in multiple index arrays will be identical…so what’s the point in allowing them? Who’s requested this feature? Just seems like another layer of complexity to what should be a simple mechanism in a graphics api. If it ain’t broke don’t fix it.

We did extensive measurements on real-world meshes, and for all but the lowest-poly real-world meshes, a single index list and normalized vertices was smaller than multiple indices.
That’s very interesting. Is that work published anywhere? I’d love to have some hard data to point to whenever this issue comes up. :smiley:

Why? Don’t you think it’s a reasonable assertion that most meshes have very few seams?
IDR, you say ‘whenever this issue comes up’ - this suggests it comes up frequently - who brings it up at ARB meetings and what reasoning do they give?
I’m very curious…is it anything to do with internet-based 3d file formats?

So in the general case most indices in multiple index arrays will be identical…so what’s the point in allowing them? Who’s requested this feature? Just seems like another layer of complexity to what should be a simple mechanism in a graphics api. If it ain’t broke don’t fix it.
Actually, I would say that it should get more complicated, not less. Ideally, vertex fetching (and some processing perhaps) should be programmatic. Some kind of program should be able to walk the vertex data as it sees fit and generate vertex attribute data as needed to feed the vertex program.

As for the point of having this, the purpose was not to make the postT&L cache more efficient. The purpose is purely memory saving (and therefore, potentially bandwidth saving).

We did extensive measurements on real-world meshes, and for all but the lowest-poly real-world meshes, a single index list and normalized vertices was smaller than multiple indices.
How many multiple indices were you using? There are, of course, tradeoffs to multiple indexing, but you can decide to index a number of parameters together (like single indexing). In general, I wouldn’t suggest having more than 2-3 sets of indices, as the size of the new index data starts competing with the size of the saved data. The idea is that your normals are more likely to cause a crease at the same place where you change texture coordinates (and, if they don’t, then you know where to have your modellers start putting creases). You can crease sets of attributes together to achieve the best possible memory savings.

And what kinds of “real world” meshes did you use?

Why? Don’t you think it’s a reasonable assertion that most meshes have very few seams?
Not really. There are quite a few texture coordinate seams for modern high-poly characters, and the bigger textures for character meshes get, the more seams there will be.

Originally posted by Korval:
In what way? The pre-T&L cache must already be able to fetch from disperate locations in memory, since we are allowed to have different vertex attributes in different VBO’s. All the multiple indexing would add is the ability to use a different index for each base pointer. It means that you have to dereference multiple indices into the memory pointers, but the accessing logic is no different than before.[/QB]
With single indices, the vertex, color, texcoords will be in the same neighborhood if you use interlacing, but with multiple indices, they may be a little too far and might effect the cache performance negitively.

Jwatte says he did some performance tests, but there is a problem here. On what GPU?
You would need a GPU emulator on a specific GPU design.

I’m not convinced that this feature would be useful. The last time someone needed this feature, was indeed someone who wanted to render a million cubes.

Jwatte says he did some performance tests, but there is a problem here. On what GPU?
You would need a GPU emulator on a specific GPU design.

That’s not what I said. I said I measured the total size of vertex data + index data when storing meshes as normalized arrays, and when storing meshes as separate arrays with separate index streams. Further, I said we measured that the overall size of the meshes was smaller with the normalized arrays. This measurement can easily be made without any specific GPU target.

When it comes to rendering, I don’t understand how you could even compare the performance. The only way to render a mesh with separate indices, using the current API, is to decode it to immediate mode. I’ve measured that that’s slower than proper VAR or VBO geometry management, many times.

Regarding what the meshes were, it was everything from a 100-poly vegetation prop, to a 2500-poly soft-skinned character. Note that the character had an artificically high seam count, because we swap textures (and geometry pieces) with quite some frequency (i e, change what shoes you’re wearing separate from your T-shirt).

If you’re doing a modern poly-reduction normal-mapped character, it still shouldn’t have more seams, assuming your mesh parameterization (UV mapping) is well done. If you use crappy automated tools, and separate texture coordinate channels for base color versus normal mapping, then it’s going to have lots of seams. But you really shouldn’t be doing that if you care about performance, nor storage size, so I’m assuming you don’t do that.

With single indices, the vertex, color, texcoords will be in the same neighborhood if you use interlacing, but with multiple indices, they may be a little too far and might effect the cache performance negitively.
Alternatively, with multiple indexing, it is possible that, when one of the indexes is repeated, the pre-T&L cache may still already have those values loaded, and therefore doesn’t need to take up the bandwidth/time to read them. The only way for the single index case to hit on the pre-T&L cache is to access the same full index twice.

I said I measured the total size of vertex data + index data when storing meshes as normalized arrays, and when storing meshes as separate arrays with separate index streams.
You never mentioned how many separate index streams you had. Or how many attributes you’re talking about.

If you’re doing a modern poly-reduction normal-mapped character
As far as I’m concerned, a “modern” character should be no less than 5000 polys, with the main character reaching 10000. Modern graphics cards can handle this many polys, so I would see this as a reasonable number.

separate texture coordinate channels for base color versus normal mapping, then it’s going to have lots of seams. But you really shouldn’t be doing that if you care about performance, nor storage size, so I’m assuming you don’t do that.
I disagree that having separate texture coordinate channels for the bump map is inappropriate. There are a number of reasons for wanting the bump map to be on a separate parameterization than the main color map.

And, since the technique we’re talking about is specifically designed to mitigate the storage cost of vertex data, such a technique becomes even more important. Considering that, as the number of texture coordinate sets increases, the number of seams increases, it is likely to become more relevant in the future, not less (as we will be wanting to have lots of texture coordinate sets with different mappings).

Originally posted by Korval:
as far as I’m concerned, a “modern” character should be no less than 5000 polys, with the main character reaching 10000. Modern graphics cards can handle this many polys, so I would see this as a reasonable number.
Even if you’re using shadow volumes, Korval?

we will be wanting to have lots of texture coordinate sets with different mappings

I don’t see this at all. I see a single, unique, mapping (a k a “parameterization”). Then I see a large number of maps mapped over this unique parameterization. The maps can be different resolution, but I think they all share the same unique texture coordinate set.

Edit: the claim that multiple index streams is to “save storage space” is fetched from thin air. The reason there are multiple index sets, is that it’s easier to build a modeling application that way. It is, however, definitely NOT the smallest way to store a mesh in any modern art pipe I’ve worked with or looked at (and I’ve looked at several).