我正在学习directx。它在如何做事方面提供了大量的自由,但可能不同的状态有不同的表现形式,并且对于表现良好的使用模式提供的指导很少。
使用directx时,通常需要在每次渲染时多次交换一堆新数据?
使用它的最明显,也可能是非常低效的方式就是这样。
Stragety 1
在每个渲染
上加载模型0的所有内容(包括纹理)并渲染它(IASetVertexBuffers,VSSetShader,PSSetShader,PSSetShaderResources,PSSetConstantBuffers,VSSetConstantBuffers,Draw)
加载模型1的所有内容(包括纹理)并渲染它(IASetVertexBuffers,VSSetShader,PSSetShader,PSSetShaderResources,PSSetConstantBuffers,VSSetConstantBuffers,Draw)
等...
我猜你可以提高效率,如果要加载的最大东西都是专用插槽,例如:如果模型0的纹理非常复杂,请不要在每一步重新加载它,只需将其加载到插槽1中并保留在那里。当然,因为我不确定DX11中每种类型的寄存器有多少,所以这很复杂(有人能指出这方面的文档吗?)
Stragety 2
选择一些纹理槽用于加载,其他纹理槽用于永久存储最复杂的纹理。
仅限
将最复杂的模型,着色器和纹理加载到专用于永久存储的插槽中
在每个渲染
上使用您预留用于加载和渲染的插槽加载模型0中尚未存在的所有内容(IASetVertexBuffers,VSSetShader,PSSetShader,PSSetShaderResources,PSSetConstantBuffers,VSSetConstantBuffers,Draw)
使用您预留用于加载和渲染的插槽加载模型1中尚未存在的所有内容(IASetVertexBuffers,VSSetShader,PSSetShader,PSSetShaderResources,PSSetConstantBuffers,VSSetConstantBuffers,Draw)
等...
策略3 我不知道,但上面可能都错了,因为我真的很陌生。
有效渲染directx(特别是DX11)以使其尽可能高效的标准策略是什么?
答案 0 :(得分: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
答案 1 :(得分:1)
其他答案是问题本身的更好答案,但到目前为止我发现的最相关的事情是this discussion gamedev.net {{3}},其中一些大型冠军游戏被描述为状态变化和抽奖调用
出现的是,大牌游戏似乎并没有真正担心这一点,即编写解决此类问题的代码需要花费大量时间,花费大量时间来编写代码。使用它可能不值得你完成申请所花费的时间。