XNA Creators Club Online
Page 1 of 1 (8 items)
Sort Posts: Previous Next

Best Method Of Drawing Lots Of Units

Last post 07/11/2009 1:43 by Craig Martin. 7 replies.
  • 02/11/2009 21:44

    Best Method Of Drawing Lots Of Units

    I have to draw lots of characters at once, each with their own model in my own vertex format. The positions change almost every step and each model is 1052 triangles, or 3156 points. I simply want to know what the best way of drawing them is. Here are the methods I've considered:


    VertexBuffer + DrawPrimitives
    This is the method I'm currently using, it's not fast enough and writing to the VertexBuffer every step has got to be inefficient, seeing as DynamicVertexBuffers are meant for this.

    DrawUserPrimitives
    I believe this is even slower, and it has too much of a triangle limit.

    DrawIndexedPrimitives
    Is this the next step up? I know that it cuts down on memory waste as you needn't define a vertex more than once, just its index. I don't know however if this actually makes a difference to speed.

    Models
    I know nothing about if and how I can use the model class to speed up drawing.

    Dynamic Buffers
    This sounds like it should be much faster, but from what I gather the Xbox doesn't like it very much. When I try to overwrite the buffer it tells me that "The array is not the correct size for the amount of data requested." Excellent.


    And that's about as far as my knowledge goes. Any help will be greatly appreciated.
    Thanks, Frozenwounds.
  • 02/11/2009 23:06 In reply to

    Re: Best Method Of Drawing Lots Of Units

    If you are modifying vertex data every frame, then DrawUserIndexedPrimitives is the best you can do I believe.

    If your models are small, you could probably take advantage of model instancing (there's a sample of it on the education catalog).
    Game hobbyist hell-bent on coding a diabolical Matrix
  • 03/11/2009 23:32 In reply to

    Re: Best Method Of Drawing Lots Of Units

    Yeah, the real question is why are you altering the vertex buffer?

    If you can fix that issues, DrawIndexedPrimitives would be the best method (Models basically use the same method).  Instancing would help as well.
  • 04/11/2009 21:38 In reply to

    Re: Best Method Of Drawing Lots Of Units

    I'm not doing anything to the vertex buffer, but changing the vertex format. It's basically the VertexPositionNormalTexture but with colour added in. I've now applied the DrawIndexedPrimitives and got a significant speed gain. However I'm still looking for more.

    Also is instancing even possible/relevant when I'm not actually using the model class?
  • 04/11/2009 21:49 In reply to

    Re: Best Method Of Drawing Lots Of Units

    Frozenwounds:
    Also is instancing even possible/relevant when I'm not actually using the model class?
    Sure it is.
    Game hobbyist hell-bent on coding a diabolical Matrix
  • 05/11/2009 2:46 In reply to

    Re: Best Method Of Drawing Lots Of Units

    Frozenwounds:
    I'm not doing anything to the vertex buffer, but changing the vertex format. It's basically the VertexPositionNormalTexture but with colour added in. I've now applied the DrawIndexedPrimitives and got a significant speed gain. However I'm still looking for more.


    Have you profiled to see where your bottleneck is now?  DrawIndexedPrimitives is pretty much as fast as you get for single models. 
    Check that you're not changing state too much. 

    If you draw like this:
    for each model
       set renderstate
       set material settings (textures, matrices, etc)
       set vertex descriptor
       set vertex buffer
       set index buffer
       begin effect
         draw indexed primitives
       end effect


    Try to reduce state changes:
    set renderstate
    set vertex descriptor
    set vertex buffer
    set index buffer
    set common material settings
    begin effect
       for each model
          set unique material settings
          effect.commitchanges

          draw indexed primitives
    end effect

    Nothing really special, just the standard technique of pulling constants values out of inner loops.
    Some trivial looking changes such as setting the vertex descriptor can be surprisingly expensive.

    There may be some pointers here too:
    http://forums.xna.com/forums/t/28824.aspx

    Frozenwounds:
    Also is instancing even possible/relevant when I'm not actually using the model class?


    Yeah, instancing is totally a GPU thing.  The default Model class doesn't support GPU instancing either, you need to modify it.

    Instancing does work best on smaller models, you may not see much improvement.  I'd make sure your rendering loop is optimized before looking at instancing.
  • 07/11/2009 1:09 In reply to

    Re: Best Method Of Drawing Lots Of Units

    I have a confession to make. I have no idea how to write shaders. So as I'm using the BasicEffect for this game at least, instancing seems a bit complicated for me yet.
    I do however, have a question. Each object class in my game has a Draw method which loops through each instance. Every vertex is transformed to world space then added to a vertex list, the indices are also stored. Then the lists are put into buffers and drawn. Now looking at this I think it may be inefficient. Am I better off just making a buffer and drawing with each one?
  • 07/11/2009 1:43 In reply to

    Re: Best Method Of Drawing Lots Of Units

    Yes thats inefficient if you are doing this every frame:

    1. Transforms on the CPU.
    2. Writing out the transformed vertices to a buffer.
    3. Sending the buffers to the GPU.

    Better to have a single vertex buffer for each object - or a single vertex buffer for each vertex type - and write the local space vertices into the vertex buffer once only

    For each different transform, set the transform on the effect and draw.

    This way all transforms are done on the GPU, you don't write to the vertex buffers each frame (only once when it's loaded) and it doesn't have to send all the vertex data to the GPU - it's already there.

    If you are wondering how you can handle multiple objects with different transforms in one large vertex buffer - there are offset parameters on the DrawIndexedPrimitives overloads.
    Game hobbyist hell-bent on coding a diabolical Matrix
Page 1 of 1 (8 items) Previous Next