在 DirectX 11 中使用索引缓冲区;它怎么知道的?

Using Index buffers in DirectX 11; how does it know?

假设我为两个不同的网格创建了两个顶点缓冲区。

     (I'm assuming creating separate buffers for separate meshes is how it's usually done)

现在,假设我想使用索引缓冲区绘制其中一个网格。 查看 Practical Rendering and Computation with Direct3D 11 这本书似乎并没有以任何方式创建索引缓冲区来引用顶点缓冲区,那么索引缓冲区如何知道(在输入组装期间) 作用于什么顶点缓冲区?

我进行了一些谷歌搜索,但没有找到答案,这让我假设我遗漏了一些明显的东西。

你是对的,索引缓冲区不引用特定的顶点缓冲区。在 DrawIndexed 期间,活动索引缓冲区用于将索引提供给活动顶点缓冲区(您使用 SetIndexBuffer/SetVertexBuffers 设置的)。

的确,索引缓冲区和顶点缓冲区是完全独立的。

索引缓冲区将在绘制时了解 VertexBuffer(例如:当两者都绑定到管道时)

您可以将索引缓冲区视为 "Lookup Table",您可以在其中保存要绘制的列表或元素索引。

这也意味着您可以将两个完全 "logically unrelated" 缓冲区附加到管道并绘制它,没有什么可以阻止您这样做,但是您当然会得到一些奇怪的视觉结果。

两者解耦都有很多优点,这里举几个例子:

  • 您可以重复使用索引缓冲区(例如,两个具有相同分辨率的置换网格可以共享同一个索引缓冲区)。这可能是一个不错的记忆增益。
  • 您可以自己绘制顶点缓冲区并对每个顶点进行一些处理(例如为精灵绘制点列表,或将 skinning/displacement 应用到流输出缓冲区,然后使用绘制生成的顶点缓冲区DrawIndexed)
  • 两个 Vertex/Index 缓冲区也可以绑定为 ByteAddressBuffer,因此您还可以在计算着色器中处理几何图形,并构建另一个优化的索引缓冲区,例如剔除三角形,然后使用优化缓冲区。使用索引而不是顶点应用这些剔除通常比顶点更快,因为您将移动更少的内存。
  • 这是一个小众案例,但有时我必须将网格绘制为一组三角形,然后绘制为一组线(某种形式的线框)。例如,如果你拿一个盒子,你不会想把对角线画成线,所以我有一个带有盒子顶点的共享 Vertexbuffer,然后一个 IndexBuffer 专用于绘制三角形列表,另一个专用于绘制线列表。对于大型模型,这也可以是一种有效的内存增益。