绘制多个网格到不同的位置(DirectX 12)

Draw multiple meshes to different locations (DirectX 12)

本文关键字:位置 DirectX 网格 绘制      更新时间:2023-10-16

我有一个问题与DirectX 12。我做了一个小的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之前被执行。所以基本上最后一个内存覆盖前面的内存。


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

感谢

不需要帮助了,我自己解决了。我为每个网格创建了恒定的缓冲区。

关于执行顺序,您是完全正确的,您的memcpy调用将立即更新缓冲区,但是命令将不会被处理,直到您将命令列表推送到队列中(并且您不会确切地知道何时会发生)。

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

所以在Direct3D12中你有几个选择,我会考虑你想画N个对象,你想在cbuffer中为每个对象存储一个矩阵。

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

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

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