【问题标题】:Draw multiple meshes to different locations (DirectX 12)将多个网格绘制到不同的位置 (DirectX 12)
【发布时间】:2016-09-30 17:31:41
【问题描述】:

我在使用 DirectX 12 时遇到问题。我制作了一个小型 3D 渲染器。模型在顶点着色器中转换为 3D 空间,基本世界视图投影矩阵位于常量缓冲区中。

要更改我当前使用memcpy(pMappedConstantBuffer + alignedSize * frame, newConstantBufferData, alignedSize) 的常量缓冲区的数据,此命令会立即替换常量缓冲区的数据。


所以问题来了,绘图被记录到一个命令列表中,稍后发送到gpu执行。

例子:

/* Now i want to change the constant buffer to change the next draw call's position to (0, 1, 0) */
memcpy(/*Parameters*/);

/* Now i want to record a draw call to the command list */
DrawInstanced(/*Parameters*/);

/* But now i want to draw other mesh to other position so i have to change the constant buffer. After this memcpy() the draw position will be (0, -1, 0) */
memcpy(/*Parameters*/);

/* Now i want to record new draw call to the list */
DrawInstanced(/*Parameters*/);

在此之后,我将命令列表发送到 gpu 执行,但要问所有网格将在同一位置,因为所有 memcpys 都在命令列表发送到 gpu 之前执行。所以基本上最后一个 memcpy 会覆盖之前的。


所以基本上问题是我如何将网格绘制到不同的位置,或者如何在命令列表中替换常量缓冲区的数据,以便常量缓冲区在 gpu 上的每次绘制调用之间发生变化?

谢谢


不再需要帮助,我自己解决了。我为每个网格创建了常量缓冲区。

【问题讨论】:

  • 你能稍微格式化一下吗?
  • @manetsus 我的问题是我需要为每个绘图调用提供不同的常量缓冲区,当您使用 memcpy 时,它会立即发生,这与记录并稍后发送执行的绘图不同:memcpy(); (更新位置以绘制网格,这会立即发生),DrawInstanced()(这被记录到列表中);,memcpy()(现在我想将位置更改为其他位置,但现在它覆盖了以前的位置),DrawInstanced( )(现在我想绘制其他网格,这将被添加到列表中)。 (现在列表将被发送到 gpu,它会将模型绘制到同一个地方,因为
  • @manetsu 第一个常量缓冲区更新被第二个覆盖
  • 所以问题是如何为每个绘图调用制作不同的常量缓冲区,或者有没有办法用 ID3D12GraphicsCommandList 更新常量缓冲区
  • 我假设您需要不同的常量缓冲区。但不确定。

标签: c++ graphics directx-12


【解决方案1】:

关于执行顺序,您是完全正确的,您的 memcpy 调用将立即更新缓冲区,但在您将命令列表推入队列之前,这些命令不会被处理(而且您不会确切知道何时会发生这种情况)。

在 Direct3D11 中,当您在缓冲区上使用 Map 时,会为您处理(如果需要,将分配一些空间以避免这种情况)。

所以在 Direct3D12 中,您有多种选择,我会考虑您要绘制 N 个对象,并且您希望在 cbuffer 中为每个对象存储一个矩阵。

首先是为每个对象创建一个缓冲区并独立设置数据。如果你只有几个,这很容易维护(并且由于资源分配而导致的额外内存占用是可以的)

另一种选择是创建一个大缓冲区(可以包含 N 个矩阵),并创建 N 个指向每个对象的内存位置的常量缓冲区视图。 (请注意,在这种情况下,您还必须遵守 256 字节对齐,请参阅 CreateConstantBufferView)。

您还可以使用 StructuredBuffer 并将所有数据复制到其中(在这种情况下您不需要对齐),并使用顶点着色器中的索引来查找正确的矩阵。 (可以在着色器中设置一个 uint 值并使用SetGraphicsRoot32BitConstant 直接应用它)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    相关资源
    最近更新 更多