9

我正在学习directx。它为如何做事提供了很大的自由度,但可能不同的策略执行不同,并且它几乎没有提供关于性能良好的使用模式可能是什么的指导。

使用directx时,每次渲染都需要多次交换一堆新数据吗?

最明显的,也可能是非常低效的使用方式是这样的。

策略 1

在每一个渲染

  1. 加载模型 0 的所有内容(包括纹理)并渲染它(IASetVertexBuffers、VSSetShader、PSSetShader、PSSetShaderResources、PSSetConstantBuffers、VSSetConstantBuffers、Draw)

  2. 加载模型 1 的所有内容(包括纹理)并渲染它(IASetVertexBuffers、VSSetShader、PSSetShader、PSSetShaderResources、PSSetConstantBuffers、VSSetConstantBuffers、Draw)

  3. ETC...

我猜如果要加载的最大的东西有专用的插槽,你可以部分提高效率,例如,如果模型 0 的纹理真的很复杂,不要在每一步都重新加载它,只需将它加载到插槽 1 中并保留它那里。当然,由于我不确定 DX11 中每种类型肯定有多少个寄存器,所以这很复杂(有人能指出这方面的文档吗?)

策略2

选择一些纹理槽用于加载,另一些用于永久存储最复杂的纹理。

只有一次

将最复杂的模型、着色器和纹理加载到专用于永久存储的插槽中

在每一个渲染

  1. 使用您为加载和渲染而留出的插槽(IASetVertexBuffers、VSSetShader、PSSetShader、PSSetShaderResources、PSSetConstantBuffers、VSSetConstantBuffers、Draw)加载模型 0 尚未存在的所有内容

  2. 使用为加载和渲染预留的插槽(IASetVertexBuffers、VSSetShader、PSSetShader、PSSetShaderResources、PSSetConstantBuffers、VSSetConstantBuffers、Draw)加载模型 1 尚不存在的所有内容

  3. ETC...

策略3 我不知道,但以上可能都是错误的,因为我真的很陌生。

在directx(特别是DX11)上进行高效渲染以使其尽可能高效的标准策略是什么?

4

2 回答 2

2

DirectX 会为您管理资源,并尽可能将它们保留在显存中以优化性能,但只能在卡中显存的限制范围内这样做。即使资源仍在视频内存中,每次状态更改也会产生开销。

优化这一点的一般策略是在渲染过程中最小化状态更改的数量。通常这意味着批量绘制使用相同纹理的所有多边形,以及批量绘制使用相同顶点缓冲区的所有对象。因此,通常您会尝试在更改状态以绘制更多图元之前尽可能多地绘制图元

这通常会使渲染代码更复杂,更难维护,因此您需要进行一些分析以确定您愿意进行多少优化。

通常,通过超出此问题范围的更通用的算法更改,您将获得更好的性能提升。一些例子是减少远处物体和遮挡查询的多边形数量。一个流行的真实短语是“最快的多边形是那些你不画的”。这里有几个快速链接:

http://msdn.microsoft.com/en-us/library/bb147263%28v=vs.85%29.aspx

http://www.gamasutra.com/view/feature/3243/optimizing_direct3d_applications_.php

http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter06.html

于 2011-06-21T23:54:57.617 回答
1

其他答案本身就是对这个问题的更好答案,但到目前为止,我发现的最相关的事情是gamedev.net上的讨论,其中一些大型游戏被描述为状态变化和抽奖。

结果是,大牌游戏似乎实际上并不太担心这一点,即编写解决此类问题的代码可能需要大量时间,而编写代码所花费的时间可能会大惊小怪不值得浪费时间完成您的应用程序。

于 2011-06-22T15:35:07.437 回答