Rendering batches of geometry

Started by
5 comments, last by nex7 15 years, 10 months ago
My engine currently batches geometry which has been sorted based on shader and texture. The only thing it does not do is transform things into the correct location. I have everything rendering accordingly and on update passes all objects have their current transformation matrices updated but I have no way to get all of those matrices into the shader when i call Draw on the vertex buffer. How is it that one would go about stuffing all of his geometry into one vertex buffer and drawing it transformed correctly. Normally i would set a world matrix in the shader for the object and render it but i can't do that if I'm rendering everything at once. thanks!
Advertisement
If I understand you correctly you have several separate objects (but with the same material) in a VB and want to render it in one call?
To do this you need to use some sort of instancing (google it). Or just do one draw call per object, this would be fairly efficient as you won't change shaders/textures and it's the standard way of doing it.
ok so the standard way of doing things is to vertex buffer everything common up and then do a draw call per unique object while setting the shader values for transformations?

so

combine verts into vert buffer until full and keep track of offsets
when buffer fills up flush through rendering thusly

for each object in the vert buffer
{
set shader for world transform of the object(and whatever else)
call render
}

rinse repeat
We sort to reduce shader/texture changes as you have done, and batch render multiple instances of the same mesh (or part of mesh... each material is seperate). You can render these with the instancing API which requires a SM3.0 card, or another way which works on any SM1 capable card, or even with software vertex processing for older hardware.

The SM1 friendly way is to store an extra element in each vertex, and to place multiple copies of the mesh in the VB and IB. Each copy has a unique index in the extra element. This index is used to look up the world transform in an array.

For ground cover, we have a seperate system to draw multiple types of plant in a single draw call, with an array of plant defintions, including size, UV range, and how much to sway.

Other methods may look at your level and put several meshes into a single VB/IB pair if they're found together. Perhaps even packing multiple textures onto a texture page to improve the number of batchable items.
"For ground cover, we have a seperate system to draw multiple types of plant in a single draw call, with an array of plant defintions, including size, UV range, and how much to sway."

how do you send this information to the shader....part of each vertex? or some other way?
The array of plant definitions is a simple array of constants, packed tightly. (ie: u1,u2,v1,v2, minscale,maxscale,sway,something is 2 constant registers per plant type). 3 or 4 grass variations, and a few flower varieties only take few constants and make a convincing field.

The ground cover is billboarded in the shader, so we render with the 4 vertices at the same location, but with a seperate value to indicate which corner the vertex is for. The ground is drawn in chunks, so it has a fairly limited XYZ range... we can take a limited input range and map it into world space... for instance using a byte for X, Y, and Z is fine. We can pack the x,y,z,corner into a D3DCOLOR. We then pack swayoffset,planttype,scale,mirroru into another D3DCOLOR.

Customized scenarios for batching are much easier to come up with than a generic "batch any set of meshes I throw at you" approach.
thanks name

This topic is closed to new replies.

Advertisement