Telanor
Telanor

Reputation: 4429

How to use instancing offsets

Suppose I have a single buffer of instance data for 2 different groups of instances (ie, I want to draw them in separate draw calls because they use different textures). How do I set up the offsets to accomplish this? IASetVertexBuffers and DrawIndexedInstanced both have offset parameters and its not clear to me which ones I need to use. Also, DrawIndexedInstanced isn't exactly clear if the offset value is in bytes or not.

Upvotes: 2

Views: 2262

Answers (1)

Drop
Drop

Reputation: 13003

Offsets

Those offsets works independently. You can offset either in ID3D11DeviceContext::IASetVertexBuffers or in ID3D11DeviceContext::DrawIndexedInstanced or in both (then they will combine).

  • ID3D11DeviceContext::IASetVertexBuffers accepts offset in bytes:

     bindedData = (uint8_t*)data + sizeof(uint8_t) * offset
    
  • ID3D11DeviceContext::DrawIndexedInstanced accepts all offsets in elements (indices, vertices, instances). They are just values added to indices. Vertex and instance offsets works independently. Index offset also offsets vertices and instances (obviously):

     index = indexBuffer[i] + StartIndexLocation
     indexVert = index + BaseVertexLocation
     indexInst = index + StartInstanceLocation
    

I prefer offsetting in draw call:

  • no byte (pointer) arithmetic needed -- less chances to make a mistake
  • no need to re-bind buffer if you just changing offset -- less visible state changes (and, hopefully, invisible too)

Alternative solution

Instead of splitting rendering to two draw calls, you can merge your texture resources and draw all in one draw call:

  • both textures binded at same draw call, branching in shader (if/else) depending on integer passed via constant buffer (simplest solution)
  • texture array (if target hardware supports it)
  • texture atlas (will need some coding, but always useful)

Hope it helps!

Upvotes: 2

Related Questions