Sign in to follow this  

Multimaterial Meshes

This topic is 2044 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have different ideas for supporting multimaterial meshes but I don't know enough about bandwidth and architecture to decide the best way.

So different materials on the mesh require multiple draw calls. Here are the different ways:

A.) I could have a VBO for the whole Mesh and a triangle Index Buffer for each material. I upload the VBO with all its data as I'm about to render the mesh, then I upload each index buffer as I'm about to draw different materials in the mesh.

B.) Another way is I have a VBO for each part of the mesh and just upload the VBO as I'm about to draw different parts.


(A) might be faster since I transfer the really heavy duty data once. All the positions, normals, tangents, texture coords, etc... The triangle indeces are more lightweight since it's just an array of ints and uploading a new index array for the different parts of the mesh wouldn't be too rough.

(B) might be faster since using method A I'm doing a lot of transfers anyway. I transfer the vertex attributes for each part of the mesh as I'm about to draw the different materials and just draw it.

Share this post


Link to post
Share on other sites
As a start: do you have evidence your system is bottlenecked by this issue? If not, choose the format easier to implement/debug.
Having a single multi-format VBO and multiple index buffers is pure nonsense. Think at it. IBs are incredibly easy: they're either 16 or 32 bit unsigned. That's it.
By contrast, every material potentially gets it own vertex format and stride.
Because of personal experience, I can tell merging different vertex formats to the same VBO is - while possible and valid - a bit troublesome to debug. There's very little reason to do so.

I don't even understand the rationale behind (B) but let's step back from a moment.

You don't need to mess with the indices in the first place. You need to issue different draw calls. Unless there's some specific need, I'd just put everything in static buffers. What is the problem you're trying to solve with uploading?

Share this post


Link to post
Share on other sites
They wouldn't be different formats. It's all just an array of position, normal, tangent, texCoord interleaved per vertex.

I don't have any evidence of slowdown since I haven't really implemented it yet and I'm just doing a bit of research ahead of time. I could try it myself and see what way is better but it's pretty hard to notice performance loss on my GTX 480. It runs super fast almost no matter what I do. I guess I could also try it on my laptop which has a 330M.

The problem I'm trying to solve with uploading is just doing it the most efficient way that will have the best FPS and take the least amount of time. So basically which way is faster?



And yeah I can just upload 1 index buffer object and use offsets with multiple draw calls. That sounds like the best way. I didn't realize there was an offset argument for the drawElements call until you mentioned it and I looked again.

So basically I'm going to upload a VBO and an IBO and make multiple draw calls with different offsets into the IBO. Genius... That'll be the least amount of sending of data to the card.

Share this post


Link to post
Share on other sites
[quote name='Hodgman' timestamp='1336637070' post='4938909']
With (A), why not (1) put the indices for every submesh into the same index-buffer (and keep track of each mesh's offset into the buffer), (2) upload the IB the same time that you upload the VB? Do the indices ever change?
[/quote]
I've to second this, it is exactly the way I'm doing it in my engine. Works like a charm.

[quote name='ill' timestamp='1336640163' post='4938922']
The problem I'm trying to solve with uploading is just doing it the most efficient way that will have the best FPS and take the least amount of time. So basically which way is faster?
[/quote]
Is this not an issue with efficient data streaming ?
You should consider when planning out your GPU data structures, that uploading your mesh is done only once, whereas rendering it will happens all the time. You can fill up the buffers over several frames without any notable impact on the running system, then, after all has been done, turn your mesh rendering on. When you stream like this and you start streaming early enough (i.e. when a entity with an unloaded mesh is still behind the corner), then you can create a seamless user experience independent of used GPU data structures.

Share this post


Link to post
Share on other sites
The way I do it is with one index buffer, sorted so that each section represents the triangles for each material.
then just draw the correct sections per material.

It won't be optimal in some cases but for the most part I found it to be the best solution.

Share this post


Link to post
Share on other sites
another way of doing it, is to have a texture atlas, render the mesh and have a vertex materialID, and in a defferd pass, apply the effects to the corresponding materialID.

Share this post


Link to post
Share on other sites

This topic is 2044 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this