如何在 Direct3D11 中正确渲染多个 3D 模型?

How to properly render multiple 3D models in Direct3D11?

经过一些搜索,我了解到可以创建多个顶点缓冲区,每个缓冲区用于一个特定的 3D 模型,并将它们设置在输入汇编程序中以供我的着色器读取,或者至少这是我可以做到的理解。但是通过阅读微软的文档,我对如何以正确的方式做到这一点感到非常困惑,this 是我正在阅读的内容,他们说我可以将一个顶点缓冲区数组传递到 IA 阶段,但是它还说我的输入汇编器在 D3D11 中可以接受的最大顶点缓冲区数是 32。如果我需要同时渲染 50 个不同的模型,我该怎么办?而且,如果有人可以阐明 pOffset 在这种情况下如何与多个模型一起工作也会有所帮助,因为我可以理解它应该始终被分配一个 0 值,因为我的缓冲区的开头始终是顶点数据,但我可以理解错误的。最后我想补充一点,我已经渲染了一些由多个模型组成的缓冲区,但我不知道我该如何处理许多单独的模型。

简短的回答是:您不会尝试在一次 Draw 调用中绘制所有模型。

您可以通过多种方式自由组织渲染,但这里是一种方法:

一个'model'由一个或多个'meshes'组成。每个网格都是顶点(在 VB 中)、索引(在 IB 中)以及与每个 'subset' 索引关联的一些 material 信息的集合。

绘制:

foreach M in models
    foreach mesh in M
        foreach part in mesh
            Set shaders based on material
            Set VB/IB based on mesh
            DrawIndexed

由于这是多个嵌套循环,因此有多种方法可以提高性能。例如,您可能只是将信息排队而不是实际调用 DrawIndexed,然后按 material 排序。然后从排序队列中调用 DrawIndexed。

要使 alpha 混合显示正确,您必须至少进行两次渲染过程:第一次渲染不透明的东西,然后第二次渲染 alpha 混合的东西。

您可能还想将给定模型中的所有内容合并为一个 VB 和一个具有偏移量的 IB,而不是使用单独的资源。

您可能在世界的多个位置拥有相同的模型,因此您可能有许多模型实例共享相同的网格数据。在这种情况下,按 VB/IB 和 material 排序可能会有用。如果您在多个位置(100s 或 1000s)绘制相同的模型,那么您应该查看 hardware instancing.

An example implementation of this can be found in DirectX Tool Kit as Model, ModelMesh, and ModelMeshPart.