Direct3D 11 中的缓冲区简介

缓冲区资源是一系列完全类型化的数据,被分组到元素中。 你可以使用缓冲区来存储各类数据,包括位置矢量、法向矢量、顶点缓冲区中的纹理坐标、索引缓冲区中的索引或设备状态。 缓冲区元素由 1 到 4 个部分组成。 缓冲区元素可以包含打包数据值(如 R8G8B8A8 表面值)、单个 8 位整数或四个 32 位浮点值。

缓冲区是作为非结构化资源创建的。 由于是非结构化的,缓冲区不能包含任何 mipmap 级别,它不能在读取时被过滤,也不能被多重采样。

缓冲区类型

Direct3D 11 支持以下缓冲区资源类型。 所有缓冲区类型都由 ID3D11Buffer 接口封装。

顶点缓冲区

顶点缓冲区包含用于定义几何图形的顶点数据。 顶点数据包括位置坐标、颜色数据、纹理坐标数据、法线数据等。

最简单的顶点缓冲区只包含位置数据。 它可进行可视化,如下图所示。

包含位置数据的顶点缓冲区的图示

更常见的情况是,顶点缓冲区包含完全指定 3D 顶点所需的所有数据。 示例可能是包含每顶点位置、法线和纹理坐标的顶点缓冲区。 此数据通常组织为每顶点元素集,如下图所示。

包含位置、法线和纹理数据的顶点缓冲区的图示

该顶点缓冲区包含每个顶点的数据;每个顶点存储三个元素(位置、法线和纹理坐标)。 位置和法线通常使用三个 32 位浮点 (DXGI_FORMAT_R32G32B32_FLOAT) 指定,纹理坐标使用两个 32 位浮点数 (DXGI_FORMAT_R32G32_FLOAT) 指定。

要从顶点缓冲区访问数据,您需要知道要访问的顶点,以及以下额外的缓冲区参数:

  • Offset - 缓冲区起点到第一个顶点数据之间的字节数量。 可以使用 ID3D11DeviceContext::IASetVertexBuffers 方法指定偏移量。
  • BaseVertexLocation - 从顶点缓冲区读取顶点之前添加到每个索引的值。

在创建顶点缓冲区之前,需要通过创建 ID3D11InputLayout 接口来定义其布局;这是通过调用 ID3D11Device::CreateInputLayout 方法完成的。 创建输入布局对象后,可以通过调用 ID3D11DeviceContext::IASetInputLayout 将其绑定到输入装配器阶段。

若要创建顶点缓冲区,请调用 ID3D11Device::CreateBuffer

索引缓冲区

索引缓冲区包含到顶点缓冲区的整数偏移量,用于更高效地渲染基元。 索引缓冲区包含一组连续的 16 位或 32 位索引;每个索引用于标识顶点缓冲区中的一个顶点。 索引缓冲区可进行可视化,如下图所示。

索引缓冲区的图示

使用以下参数查找存储在索引缓冲区中的连续索引:

索引缓冲区开始位置 = 索引缓冲区基址 + 偏移量(字节)+ StartIndexLocation * ElementSize(字节);

在该计算公式中,ElementSize 是每个索引缓冲区元素的大小(两个或四个字节)。

若要创建索引缓冲区,请调用 ID3D11Device::CreateBuffer

常量缓冲区

常量缓冲区让你能够高效地向管道提供着色器常量数据。 你可以使用常量缓冲区存储流输出阶段的结果。 从概念上讲,常量缓冲区看起来就像单元素顶点缓冲区,如下图所示。

着色器-常量缓冲区的图示

每个元素存储 1 到 4 个组件常量(由所存储数据的格式决定)。 若要创建着色器常量缓冲区,请调用 ID3D11Device::CreateBuffer 并指定 D3D11_BIND_FLAG 枚举类型的 D3D11_BIND_CONSTANT_BUFFER 成员。

常量缓冲区只能使用单个绑定标志 (D3D11_BIND_CONSTANT_BUFFER) ,不能将其与其他任何绑定标志结合使用。 若要将着色器常量缓冲区绑定到管道,请调用以下方法之一: ID3D11DeviceContext::GSSetConstantBuffersID3D11DeviceContext::P SSetConstantBuffersID3D11DeviceContext::VSSetConstantBuffers

若要从着色器读取着色器常量缓冲区,请使用 HLSL 加载函数 (例如 Load) 。 每个着色器阶段允许最多 15 个着色器-常量缓冲区;每个缓冲区可包含最多 4096 个常量。

缓冲区