Why Directx11 doesn't support multiple index buffers in IASetIndexBuffer

391 views Asked by At

You can set multiple vertex buffers with IASetVertexBuffers, but there is no plural version of IASetIndexBuffer. What is the point of creating (non-interleaved) multiple vertex buffer datas if you wont be able to refer them with individual index buffers

(assume i have a struct called vector3 with 3 floats x,y,z)

let say i have a model of human with 250.000 vertices and 1.000.000 triangles;

  • i will create a vertex buffer with size of 250.000 * sizeof(vector3) for vertex LOCATIONS and also,
  • i will create another vertex buffer with size of 1.000.000 * 3 * sizeof(vector3) for vertex NORMALS (and propably another for diffuse texture)

i can set these vertex buffers like:

ID3D11Buffer* vbs[2] = { meshHandle->VertexBuffer_Position, meshHandle->VertexBuffer_Normal };
uint strides[] = { Vector3f_size, Vector3f_size };
uint offsets[] = { 0, 0 };
ImmediateContext->IASetVertexBuffers(0, 2, vbs, strides, offsets);

how can i set seperated index buffers for these vertex datas if IASetIndexBuffer only supports 1 index buffer

and also (i know there are techniques for decals like creating extra triangles from the original model but) let say i want to render a small texture like a SCAR on this human model's face (let say forehead), and this scar will only spread through 4 triangles, is it possible creating a uv buffer (with only 4 triangles) and creating 3 different index buffers for locations, normals and UVs for only 4 triangles but using the same original vertex buffers (same data from full human model). i dont want to create tonnes of uv data which will never be rendered beside characters forehead (and i dont want to re-use, re-create vertex position datas for this secondary texture layers (decals))

EDIT: i realized i didnt properly ask a question, so my question is:

  • did i misunderstand non-interleaved model structure (is it being used for some other reason instead having non-aligned vertex components)?
  • or am i approaching non-interleaved structure wrong (is there a way defining multiple non-aligned vertex buffers and drawing them with only one index buffer)?
1

There are 1 answers

0
mrvux On

The reason you can't have more than on Index buffer bound at a time is because you need to specify a Fixed number of primitives when you make a call to DrawIndexed.

So in your example, if you have one index buffer with 3000 primitives and another with 12000 primitives, the pipeline would have no idea how to match the first set to the second set.

If is generally normal that some vertex data (mostly position) eventually requires to be duplicated across your vertex buffer, since your buffers requires to be the same size.

Index buffer works as a "lookup table", so your data across vertex buffers need to be consistent.

Non interleaved model structure has many advantages:

First using separate buffers can lead to better performances if you need to draw the models several times and some draws do not require attributes.

For example, when you render a shadow map, you will need to access only positions, so in interleaved mode, you still need to bind a large data structure and access elements in a non contiguous way (Input Assembler does that). In case of non interleaved data, Position will be contiguous in memory so fetch will be much faster.

Also non interleaved allows to more easily do some processing on some attributes, it is common nowadays to perform some displacement or skinning in a compute shader, so in that case you can also easily create another Position+Normal buffer, perform your skinning on those and attach them in the pipeline once processed (And you can keep UV buffer intact).

If you want to draw non aligned Vertex buffers, you could use Structured Buffers instead (and use SV_VertexID and some custom lookup tables in your shader code).