Multiple objects in one buffer or just one object?

Started by
7 comments, last by Krohm 10 years, 7 months ago

I'm having some issues thinking about the whole design of this.If I have a 200k vertex terrain,it's probably to split it into multiple vertex & index buffers,but what if i have a simple cube?Would it be wise to put just the cube in a vertex & index buffer?

Some time ago,nvidia recommended having 200 triangles in a vertex buffer(if you use indexing),does anybody know what the right number would be now?

Advertisement

200 triangles? yeah maybe like 10 years ago.. iirc nvidia reckons about 1-2mb worth of data per buffer is good. But there is no one way to do it, you need to go test and profile your app over and over.

yea,the info i got is aproximately that old...still...puting 20 objects in one buffer,may prove to create bottlenecks in finding the rights textures,and effects to be applied...

It's best to try and batch together all the same textures, buffers, shaders etc. to minimize expensive state switching. If you don't know already you might want to look into Instancing as well :)

even with instancing....there will be may changes...i guess i'll create some kind of manager for all of this....

i'll make the goal 2 mb for each vertex buffer.


even with instancing....there will be may changes...i guess i'll create some kind of manager for all of this....

i'll make the goal 2 mb for each vertex buffer.

unless you have a LOT of meshes with one texture, you'll never get there.

2 meg of vertices?

"some kind of manager" is the right way to go.

apparently it's called a "render queue". i call mine a "drawlist" (a list of stuff to draw, duh!) <g>.

as stated "state changes" are costly (time wise).

what you want to do is make sure your manager (render queue) sorts drawing on the most to least expensive state changes.

to the best of my knowledge, the relative costs of state changes are as follows (highest to lowest):

1. binding a texture.

2. binding a vertex buffer

3. binding an index buffer

4. material changes

5. constant buffers
6. other state changes (alpha test, cull, clamp, etc)

unless you put everything in one buffer then draw ranges (sections of the buffer) based on texture, its unlikely you'll ever get to 2 meg for a vertex buffer. even less likely for an index buffer.

but then again, you might. each game is different.

in my case, an efficient data layout sorted just on texture, not even mesh or near to far, combined with state management while drawing for the rest, allows me to do ~10,000 small static meshes of 4-100 vertices each, AS SEPARATE BUFFERS AND CALLS IN FIXED FUNCTION PIPELINE with no problems. read my signature block. below.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

"DirectX is like a belt fed machine gun, where every texture change is like hand loading in a new belt of ammo. worse, every mesh (vb) is a new belt of ammo, and a texture is like breaking the gun down, and setting it up again elsewhere, then loading it, then spraying triangles again. so you want to setup the gun once, string all your belts together, load it once, then just spray."

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

yea,the info i got is aproximately that old...still...puting 20 objects in one buffer,may prove to create bottlenecks in finding the rights textures,and effects to be applied...

1 buffer != 1 draw call.

If you're making one draw call / drawing one "batch" / one "sub-mesh", then yes, you can only be reading from one set of vertices, one set of textures, one shader etc...

But that doesn't make the opposite true. One shader can be used by many batches. One vertex buffer can be used by many objects, etc...

You can use offsets to store many different 200-triangle objects in different parts of the one vertex buffer, and then draw each of those objects separately if you wanted to. If you use the same buffer, you just have the option of drawing them together if you want to. Just how if two meshes share the same texture/shader, you have the option of drawing them in one batch.

While minimizing buffer changes is good, it is not so critical to require you to crack your head open IMHO.

Professionals might disagree on that but I am a supporter of multiple iterations as better way to do things.

What I suggest to do is to have "homogeneous" vertex buffers. That is, if you have two objects, put them in the same buffer only if their vertex blob has the same format. Main reason to do that is debugging. It is also possible to put everything in a single buffer but dealing with format changes is painful in debuggers such as PIX. My testing confirmed there's no much of a big deal in reducing buffer count to the extreme - as I expected since my data set is pretty homogeneous.

I would consider putting each terrain mesh in its own buffer, on a per-terrain basis for easiness.

A single cube instead would be merged in the compatible buffer - unless it's dynamically loaded in which case I would just put it in its own buffer just because I don't want to regen the data already stored.

If you do things right, there's no problem such as "bottlenecks in finding the rights textures,and effects to be applied". It's known since beginning what object ends up where in the buffer. Many people seems to forget that fact. They first throw away information, then crack their heads (and CPU) to get it back each frame.

Previously "Krohm"

This topic is closed to new replies.

Advertisement