在 d3d11 中渲染多对象场景的正确方法是什么

What is the proper way to render multiobject scenes in d3d 11

如果我想渲染一个特定的网格,我创建它的 vertex/index 数据,创建顶点缓冲区、索引缓冲区,将它们绑定到 IA,设置所需的着色器并调用 context->DrawIndexed。我想渲染多个对象的一个​​选项是为每个对象循环此过程,但在 msdn 上它说“输入程序集(IA):您需要为场景中的每个对象附加每个顶点和索引缓冲区。”。我假设这意味着通过单个 Draw 调用绘制多个对象。

顶点缓冲区有槽号(假设每个对象的顶点缓冲区都有一个槽),但索引缓冲区没有这样的东西吗?有人可以给我举一些例子吗?

我说的论文:https://docs.microsoft.com/en-us/windows/win32/direct3dgetstarted/understand-the-directx-11-2-graphics-pipeline

Direct3D 是一种 low-level 图形 API,因此您可以通过多种方式渲染对象。

基本渲染的一个常见模型是将每个网格组织为顶点缓冲区、索引缓冲区和共享相同 material/surface 属性的 'subsets' 列表(一组顶点着色器、像素着色器、纹理资源等)。

See DirectX Tool Kit for an example of the Model/Mesh/MeshPart organization for rendering.

例如,这个模型:

它由一个VB,一个IB组成,还有'two subsets',一个用于外部纹理,另一个用于内部无纹理。因此,此场景需要两次调用 DrawIndexed.

如果您想渲染此网格的多个 (n) 个实例,您将使用相同的 VB、相同的 IB 和相同的纹理资源,但通常顶点着色器会应用变换,以便您可以将其定位在场景中。因此,您将使用纹理调用 DrawIndexed n 次,而没有纹理调用 n 次。

对于顶点缓冲区布局和着色器签名的每种组合,您还需要一个输入布局对象,您可以在此处将其安排为一个 IL。

虽然此模型没有任何透明度,但您还需要记住 'alpha-blended' 子集通常必须渲染 所有不透明子集渲染之后即使使用 z-buffer 隐藏表面移除也能获得预期结果。

There are many other ways to optimize drawing many copies of the same mesh. For example, you could use instancing to draw many copies of the outside of the cup in one call to DrawIndexedInstanced and then draw all the interiors of the cup in a second call. See SimpleInstancing. You'd need a different Input Layout, Vertex Shader, and additional VB stream to provide and use the instancing data.

PS: 现在的游戏大多调用DrawIndexed几千、几万次,刚上手的时候不要担心优化太多