Different methods of handling rendering - Which is faster?

Started by
8 comments, last by onnel 21 years, 7 months ago
If I have multiple identical models to be rendered, is it faster to put a single copy in a vertex/index buffer and then render this multiple times with different transformations or is it faster to transform the pixels as needed per object and then put them all in a single vertex/index buffer? The former means you don't have to transform the actual vertices in your own code, you simply use the matrix transform to correctly place each object. This is efficient in that you're not locking/unlocking the buffers, but it also means you're not getting near the ideal number of vertices in the buffers for rendering/call (I'm basing this on DirectX rendering of indexed buffers). The latter would require the vertices for each object to be transformed every render and then inserted in to the buffers. This can, I think, be done with only a single lock of the buffers and will mean that the vertices are nearer to their optimal size. Are there any other options? Is one of these options clearly better? Will it depend on whether you're rendering 10s or 1000s of objects? Any suggestions? How are others handling this? What about if the vertices for the objects are identical, but the textures and materials are different? Onnel [edited by - onnel on September 13, 2002 4:54:29 AM]
Advertisement
As a lot of hardware (GeForce+, Radeon+, Parhelia) nowadays supports transformation in hardware, you''d be wasting resources doing all dransformations in software. Note that you don''t have to put all objects in seperate vertex/index buffers; in fact, that''s a huge waste, so put as many meshes in one vertex/index buffer as possible. New graphics cards just love static buffers.

- JQ
Full Speed Games. Period.
~phil
I''m definitely with oyu on everything you wrote, but a few additional questions:

When you talk about putting many meshes in a single buffer, that means that those meshes must have their vertices in world coords (since you cannot specify different transforms for multiple objects in the same buffer) and that all of the objects must have the same texture and materials.

Based on this, I''ll try and minimize the number of different buffers I have to use by making sure that objects with the same texture in buffers (I already do this). My problem is with moving objects, though. since I need global coordinates in the buffer, then I''m going to have to do the transformation on the cpu before inserting the vertices in to the buffer. This goes directly against your advice (which KI think is good) to push the transformation to the video card.

I realise that vertex shaders could be used to address the issue, but I''d like to be able to support older cards which don''t have vertex shaders (what''s the oldest card to have a vertex shader implementation? GF3?)

Onnel

P.S. As always, thanks for your replies. We seem to browse at the same time!
If you use a vertex-shader you can specify a different transform matrix on a per-vertex basis by having an extra piece of data in your vertex structure that specifies which matrix to use. Then you just need to upload a bunch of matrices into you VS constant space and you can render several instances of the same model.

Say you''ve got a model that you''re going to plotting lots of times a frame, you make a vertex-buffer with several copies of the object in it, but each copy has a different matrix ID set into it''s vertices. Then when you come to render these objects you can render them in batches by uploading several matrices and calling DrawPrimitive with the appropriate no of vertices for the no of models that you want to plot out of your VB (e.g. if you create a VB with 5 copies of a 200 vert mesh, and you want to render 12 meshes you''d render 5*200 verts, 5*200 verts and then 2*200 verts, with appropriate matrix uploads in between).

Hope that makes some sense to someone
Iain HutchisonProgrammer, Silicon DreamsThe views expressed here are my own, not those of my employer.
pieman, everything you wrote about vertex shaders makes sense..my only worry is support. What cards support vertex shaders at speeds that make this approach worthwhile? The whole point is to do something faster than either performaing the transformation on the vertices on the CPU before transmitting them or having to perform lots of individual calls to render (one for each transformed mesh).

Vertex shaders definitely fix the issues with those two methods, but are they supported widely and well enough to make it a faster solution for most users?

What method are most games these days using?

Onnel
quote:Original post by onnel
When you talk about putting many meshes in a single buffer, that means that those meshes must have their vertices in world coords (since you cannot specify different transforms for multiple objects in the same buffer) and that all of the objects must have the same texture and materials.

That''s a 100% misconception. You don''t have to render the entire vertex buffer at once. You can do as many Draw*Primitive() calls for parts of one vertex buffer as you like. Same goes for index buffers. That means all the other problems you stated are pretty much irrelevant.

- JQ
Full Speed Games. Period.
~phil
Quest, I thought that this answered everything, but it would seem that I'm still going to be doing DrawPrimitive calls with far less than the optimal number of vertexes (since I'll have to be readjusting the transformation and rendering speerately for every instance of the mesh in the buffer). At that point, it's no difference than having a single copy of the mesh in the buffer and just rendering the whole buffer multiple times with different transformations.

Can you spell it out for me a bit more?

Onnel

[edited by - onnel on September 13, 2002 7:22:24 AM]
quote:Original post by onnel
Quest, I thought that this answered everything, but it would seem that I''m still going to be doing DrawPrimitive calls with far less than the optimal number of vertexes (since I''ll have to be readjusting the transformation and rendering speerately for every instance of the mesh in the buffer). At that point, it''s no difference than having a single copy of the mesh in the buffer and just rendering the whole buffer multiple times with different transformations.

Well yeah, basically that''s how you usually do it. If your objects are static you might want to create copies for every instance in the vertex buffer (all in the same one) - but make sure it doesn''t use up TOO much memory. (i.e. mainly useful for small objects that are strewn all over the place) That doesn''t mean you can''t use the buffer for anything else as well, though.
The optimum solution can of course only be found through experimenting, so you might want to do that.

- JQ
Full Speed Games. Period.
~phil
Great...I understand the alternatives now and am confident that i''m not missing any huge pieces of the puzzle. Now it''s time for me to try the various alternatives out!

Thanks again for giving me the dumb downed version.

Onnel
quote:Original post by onnel
Great...I understand the alternatives now and am confident that i'm not missing any huge pieces of the puzzle. Now it's time for me to try the various alternatives out!
Yeah, at least, those are the alternatives I am aware of, although I haven't seen anyone complain about my posts so far.
quote:Thanks again for giving me the dumb downed version.
It's not really much more complicated than how I described it. I think.

- JQ
Full Speed Games. Period.

[edited by - JonnyQuest on September 13, 2002 9:32:05 AM]
~phil

This topic is closed to new replies.

Advertisement