3d 如何在DirectX 11中实现unity中的静态批处理

3d 如何在DirectX 11中实现unity中的静态批处理,3d,directx,sharpdx,3d,Directx,Sharpdx,作为unity用户,我对如何实现类似于静态批处理的东西感到困惑。 多个网格(不同的网格但相同的材质)显示为在1次绘制调用中渲染,但我不知道如何在DirectX中实现这一点 我可以看到如何使用draw()在DirectX中绘图。我知道可以在一次调用中多次绘制相同的网格(DrawiInstanced()?),但是我不知道如何在一次绘制调用中绘制多个不同的网格。我希望被指向正确的方向,或者给我一个示例,比如说一个立方体&一个三角形在一次绘制调用中呈现,共享一种材质 我使用的是DirectX11.1&通

作为unity用户,我对如何实现类似于静态批处理的东西感到困惑。 多个网格(不同的网格但相同的材质)显示为在1次绘制调用中渲染,但我不知道如何在DirectX中实现这一点

我可以看到如何使用draw()在DirectX中绘图。我知道可以在一次调用中多次绘制相同的网格(DrawiInstanced()?),但是我不知道如何在一次绘制调用中绘制多个不同的网格。我希望被指向正确的方向,或者给我一个示例,比如说一个立方体&一个三角形在一次绘制调用中呈现,共享一种材质

我使用的是DirectX11.1&通过SharpDX来实现这一点,我更喜欢SharpDX示例,但是DX示例也不错,但是没有DX9/10示例如果正确的方法发生了变化,我只对DX11感兴趣


谢谢。

没有自动执行此操作的机制,但是如果您有多个共享输入布局和“材质”(着色器、纹理等)的网格,您可以简单地连接顶点和索引缓冲区(根据需要将索引修补到基顶点偏移)

作为绘制立方体和三角形的示例,只需将VB设置为同时包含以下两种图形:

float cubeAndTriangleVertices[] = 
{
  -1, -1, -1, // cube vertices
  -1, -1,  1,
  -1,  1, -1,
  -1,  1,  1,
   1, -1, -1,
   1, -1,  1,
   1,  1, -1,
   1,  1,  1,
   2,  0,  0, // triangle vertices
   2,  1,  0,
   3,  0,  0,
};
D3D11_SUBRESOURCE_DATA cubeAndTriangleVData = { cubeAndTriangleVertices };
device->CreateVertexBuffer(&cubeAndTriangleVData, &vb);

unsigned short cubeAndTriangleIndices[] =
{
  0, 2, 1, 2, 3, 1, // -x face
  7, 6, 5, 6, 4, 5, // +x face
  0, 1, 4, 4, 1, 5, // -y face
  2, 6, 3, 6, 7, 3, // +y face
  6, 2, 0, 4, 6, 0, // -z face
  3, 7, 1, 7, 5, 1, // +z face
  8, 9, 10, // triangle
}

D3D11_SUBRESOURCE_DATA cubeAndTriangleIData = { cubeAndTriangleIndices };
device->CreateIndexBuffer(&cubeAndTriangleIData, &ib);

// ...pipeline setup

context->DrawIndexed(6 * 6 + 3, 0, 0);

没有自动执行此操作的机制,但如果有多个共享输入布局和“材质”(着色器、纹理等)的网格,则可以简单地连接顶点和索引缓冲区(根据需要将索引修补到基本顶点偏移)

作为绘制立方体和三角形的示例,只需将VB设置为同时包含以下两种图形:

float cubeAndTriangleVertices[] = 
{
  -1, -1, -1, // cube vertices
  -1, -1,  1,
  -1,  1, -1,
  -1,  1,  1,
   1, -1, -1,
   1, -1,  1,
   1,  1, -1,
   1,  1,  1,
   2,  0,  0, // triangle vertices
   2,  1,  0,
   3,  0,  0,
};
D3D11_SUBRESOURCE_DATA cubeAndTriangleVData = { cubeAndTriangleVertices };
device->CreateVertexBuffer(&cubeAndTriangleVData, &vb);

unsigned short cubeAndTriangleIndices[] =
{
  0, 2, 1, 2, 3, 1, // -x face
  7, 6, 5, 6, 4, 5, // +x face
  0, 1, 4, 4, 1, 5, // -y face
  2, 6, 3, 6, 7, 3, // +y face
  6, 2, 0, 4, 6, 0, // -z face
  3, 7, 1, 7, 5, 1, // +z face
  8, 9, 10, // triangle
}

D3D11_SUBRESOURCE_DATA cubeAndTriangleIData = { cubeAndTriangleIndices };
device->CreateIndexBuffer(&cubeAndTriangleIData, &ib);

// ...pipeline setup

context->DrawIndexed(6 * 6 + 3, 0, 0);

我想知道这是如何工作的,因为我不知道如何提交多个网格,即使它们在绘图调用中位于同一缓冲区中。我是否正确地理解了它的工作原理,因为您正在使用DrawIndexed进行绘制,因此可以指定面?到目前为止,我只使用了draw(因此多边形是按照它们在缓冲区中的顺序绘制的),因此我没有看到这是如何可行的。如果不指定面,就无法执行相同的操作,我的假设正确吗?没有魔法绘制(Model1Index、Model2Index、Model3Index)或类似功能?@RonanThibaudau您应该能够将网格组合到同一个顶点缓冲区,即使您使用的是非索引绘制调用(尽管今天几乎所有的游戏都使用DrawIndexed)。要将我的答案中的代码转换为非索引代码,只需创建一个包含(6*6+3)个顶点的新顶点缓冲区,每个顶点的值等于顶点[Indexes[i]]。这里的关键概念是,D3D并不真正关心“网格”-如果你有多个具有相同着色器、纹理等的网格,那么它基本上可以将其视为单个对象。事实上,我明白我现在的困惑所在,如果我提交V1 V4 V6,我将得到V1 V2 V3面&V4 V5面,在三角形列表中,顶点3和4之间不会有太长的距离,我正在考虑另一种布局(每个顶点集有三个,所以1 2 3/2 3 4/3 4 5等)。因此,我认为我设计了一个不存在的问题。我想知道这是如何工作的,因为我不知道如何提交多个网格,即使它们在绘图调用中位于同一缓冲区中。我是否正确地理解了它的工作原理,因为您正在使用DrawIndexed进行绘制,因此可以指定面?到目前为止,我只使用了draw(因此多边形是按照它们在缓冲区中的顺序绘制的),因此我没有看到这是如何可行的。如果不指定面,就无法执行相同的操作,我的假设正确吗?没有魔法绘制(Model1Index、Model2Index、Model3Index)或类似功能?@RonanThibaudau您应该能够将网格组合到同一个顶点缓冲区,即使您使用的是非索引绘制调用(尽管今天几乎所有的游戏都使用DrawIndexed)。要将我的答案中的代码转换为非索引代码,只需创建一个包含(6*6+3)个顶点的新顶点缓冲区,每个顶点的值等于顶点[Indexes[i]]。这里的关键概念是,D3D并不真正关心“网格”-如果你有多个具有相同着色器、纹理等的网格,那么它基本上可以将其视为单个对象。事实上,我明白我现在的困惑所在,如果我提交V1 V4 V6,我将得到V1 V2 V3面&V4 V5面,在三角形列表中,顶点3和4之间不会有太长的距离,我正在考虑另一种布局(每个顶点集有三个,所以1 2 3/2 3 4/3 4 5等)。所以我想我设计了一个不存在的问题。