2009-11-20 66 views
1

我有一个运行的3D引擎内置在D3D(通过SlimDX)。为了避免中断渲染管道,我将具有相同材质的多个对象组合成更大的网格(以减少状态切换)。这工作得很好,并为我的需要提供了良好的性能水平。D3D性能比较,着色器vs内置阴影

我遇到的问题是我在运行期间需要更改这些较大批量网格的某些子集上的材料属性。我正在使用属性缓冲区,它一直工作得很好。我之前一直在使用有限数量的活动属性(每个网格约5个),但现在发现需要在材质(不透明度/色彩搭配的不同色调)上有更多变化,因此可能会有数百个或更多的组合。而且由于这些更改在运行时发生,我无法在渲染开始之前将它们捆绑在一起。当然,我可以重新构建网格,但我宁愿不要,因为它速度很慢,并且材料之间的切换需要以交互速度完成。

所以我的问题是,最好的路线是什么?

  • 我应该实行动态口罩随叫随到属性ID面临着一个更强大的属性处理系统,然后完成时对它们进行复位?我听说属性缓冲区中的碎片会产生额外的性能影响,并且我也不确定后续DrawSubset()调用与之间的材质切换(即何时过多以及何时应优化属性数组?)的性能影响。任何有此经验的人?

  • 我的另一个想法是使用参数化像素着色器。我不需要任何奇特的效果,只是最低限度的(当前是内置的平面着色器,只有颜色和一些对象的透明度),所以着色器模型1已经足够满足我的需求。这里的想法是使用一个通用着色器,而不是在调用之间切换材质,只是改变一些着色器参数。但是我不知道这是否比切换材质更快,或者如果可编程着色器比构建时更慢(给出相同的结果)。

我也好奇切换目或在一个大的网格绘制不同子集(给定相同数量的材料开关,用于这两种情况下)之间的性能命中的差异。

我知道这些问题可能会在GFX卡和它们各自的性能/年龄之间有所不同,但我只是在这里寻找关于什么是最关注的一般指南(即什么类型的状态切换/ CPU干扰这给了最大的GPU命中)。内存也是一个问题,所以任何复制整个(或大部分)网格的实现对我来说都是不可能的。

我的注意力集中在较老的(5y)/功能较弱/集成的GFX卡上,而不一定是顶级的游戏卡或工作站卡(如Quadro)。我猜想使用着色器可以制作或破解解决方案,具体取决于特定电路板上着色器的性能。

任何和所有的建议和反馈,非常感谢。

非常感谢提前!

回答

3

改变着色器参数将会很慢。理想情况下,您希望编写基于Shader 2的着色器,将大部分属性缓冲区上载到图形卡。然后你有一个per-vertex属性字段可以选择适当的属性缓冲区。

您的表现问题将来自您使用的绘图调用次数。越多的抽奖电话使用越多的性能受到影响。对着色器常量或纹理的任何更改都需要新的DIP调用。你想要做的就是尽量减少着色器常量修改的数量和DIP调用的数量。

它成为一个相当复杂的过程思想。

例如,如果您正在处理一个骨骼模型,其中有64个骨骼,那么您有2个选项。 1为每个骨骼的网格数据设置世界矩阵并调用DIP。或者,您可以一次加载尽可能多的骨骼矩阵,并在顶点上使用一个值来选择要使用的骨骼,并调用DIP一次。第二个会更快。你可能会发现你可以很容易地以这种方式做一些基于多骨的蒙皮。

这适用于导致着色器不断变化的任何事情。请注意,即使您可能使用固定功能管道,但大多数现代图形硬件(即自2002年发布Radeon 9700以来的任何图形硬件)都会将固定功能转换为基于着色器,因此应用相同的性能问题。

基本上,避免任何事情的东西都是导致您进行另一次DIP拨号的任何事情。很显然,为了避免这样做而做到这一点是不切实际的,而且某些变化的成本较低。作为一个粗略的经验规则,按照费用顺序,要避免的事情如下:(被警告已经有一段时间了,因为我测试了这个,所以你可能想对这个主题做一些测试和替代读数)

1)改变着色
2)改变纹理
3)改变着色恒定
4)改变顶点缓存
5)改变索引缓冲区

1是迄今为止最昂贵的。

与其余的相比,4和5相当便宜,但是不同的顶点格式可能会导致更大的问题,因为它可能会导致着色器被更改。

编辑:我不完全确定为什么改变常量伤害如此之多。我原以为这样的改变会顺利进行。也许在现代硬件上它不是这样的问题。在一些早期的硬件上,常量被编译到着色器中,所以改变常量会导致着色器发生完全变化。

与任何你最好的尝试,看看会发生什么。

排序所有呼叫的一个有趣的解决方案可以使用排序键,其中前8位给你一个着色器ID。接下来的10位纹理等等。然后,您执行正常的数字排序,并且您可以使用不同的排序顺序轻松地播放,以查看提供最佳性能的东西:)

Edit2:值得注意的是,任何改变像素着色器状态的变化都会比改变顶点缓冲区状态,因为它在管道中更深。因此它需要更长的时间才能通过...

+0

好点。正如你所说,改变着色器常量强制一个新的DIP(从我猜测下面的DrawSubset)。在设置默认着色器和在默认着色器上设置漫反射颜色时,性能损失差异是什么?或者有没有?为什么顶点/索引缓冲区切换更快?是否因为改变材质选项“断开”管道并影响渲染后端的更多状态更改?在哪里我可以找到这些时间汇的大约比率(或者它在制造商和型号之间变化太大)? – Burre 2009-11-23 09:42:55