我有一个内置在 D3D 中的正在运行的 3D 引擎(通过 SlimDX)。为了避免打断渲染管道,我将许多具有相同材质的对象组合成更大的网格(以减少状态切换)。这运作良好,并为我的需要提供了良好的性能水平。
我遇到的问题是,在运行期间,我需要更改那些较大批量网格的某些子集的材质属性。我为此使用了属性缓冲区,并且它运行得相当好。我之前一直在使用有限数量的活动属性(每个网格大约 5 个),但现在发现需要对材料有更多的变化(不同的不透明度/颜色混合),因此最终可能有数百个或更多的组合。而且由于这些更改发生在运行时,我无法在渲染开始之前将它们捆绑在一起。当然我可以重新构建网格,但我宁愿不这样做,因为它很慢,并且需要以交互速度在材质之间切换回来和第四次。
所以我的问题是,最好的路线是什么?
我是否应该实现一个更强大的属性处理系统,根据需要使用可用的属性 ID 动态屏蔽面部,然后在完成后重置它们?我听说属性缓冲区中的碎片会产生额外的性能影响,我也不确定后续 DrawSubset() 调用之间的材料切换(即何时太多以及何时应该优化我的属性数组?)。有这方面经验的人吗?
我的另一个想法是使用参数化像素着色器。我不需要任何花哨的效果,只需要最低限度(当前是内置的平面着色器,仅具有颜色和某些对象的透明度),因此着色器模型 1 足以满足我的需求。这里的想法是使用一个通用着色器,而不是在调用之间切换材质,只需更改一些着色器参数。但我不知道这是否比切换材质更快和/或可编程着色器是否比内置着色器慢(给出相同的结果)。
我也很好奇切换网格或在一个大网格中绘制不同子集之间的性能差异(两种情况下的材质切换数量相同)。
我知道这些问题在 GFX 卡及其各自的性能/年龄之间可能会有所不同,但我只是在这里寻找一般指导方针,了解最关注什么(即哪种类型的状态开关/CPU 干扰最大) GPU命中)。内存也是一个问题,因此任何复制整个(或大部分)网格的实现对我来说都是不可能的。
我的重点是较旧(5 年)/功能较差/集成 GFX 卡的性能,而不一定是顶级游戏玩家卡或工作站卡(如 Quadro)。我猜这可能会根据特定板上着色器性能的好坏来使用着色器来制造或破坏解决方案。
非常感谢任何和所有建议和反馈。
提前谢谢了!