Answers:
剔除是一种性能优化。因此,仅出于此目的而这样做是没有意义的。你必须有一个理由。
GPU(不是XNA Framework)以惊人的速度剔除三角形和像素。您提交的每个三角形都必须进行变形(通过顶点着色器)。然后,它会剔除那些落在屏幕上的东西。然后,它将填充其余的三角形,以剔除屏幕外的像素。然后,其余像素(通过像素着色器)绘制到后台缓冲区。
(当我说“然后”时,实际上是在大规模并行管道中完成所有这些操作。)
因此,您可能必须剔除单个三角形是非常罕见且不寻常的。要达到顶点极限,您必须绘制大量的三角形。要达到填充率,纹理获取或像素阴影限制,通常需要具有很高的深度复杂度(在这种情况下,视口/视锥剔除将无济于事)。
因此,将几何图形显示在屏幕外通常很少或没有成本。
成本(尤其是在绘制“对象”(通常是3D对象)的情况下)实际上是首先将这些对象提交给GPU。提交太多对象,您达到了批次限制(每帧获得数千*批次)。
因此,如果实施平截头剔除,则可以减少提交给GPU的批处理数量。如果您的批次受到限制-这可以使您不受限制。
现在-您的问题是关于2D XNA-因此大概您正在使用SpriteBatch
。这有点不同。
毫无疑问,它被称为“ Sprite Batch ”。它正在做的是拿起您绘制的精灵,并尽最大可能通过将它们组合在一起,尽可能少地将这些精灵提交给GPU 。
但是,在以下情况下,SpriteBatch将被迫开始新的批处理:
因此,如果您遇到第一个选择,则剔除是一个合适的优化。如果您发送的Sprite数量如此之多,以至于最终批次过多(您可能也会消耗带宽-但我很确定您会首先达到批次限制)。通常只有在您拥有一个真正巨大的世界时,才会发生这种情况-因此,在这种情况下,您通常可以通过非常简单,快速但不准确的剔除来摆脱困境。
现在-如果您进行了足够的纹理交换以使您超过批处理限制,并且其中许多实际上不在屏幕上,则将它们剔除将使您低于批处理限制。然后,是的-剔除是一种有效的优化方法。
但是,在这种情况下,更好的优化方法是使用纹理图集(又名:精灵图)。这使您可以减少纹理交换的次数,从而减少批处理的次数- 无论屏幕上显示的内容是什么还是关闭的内容。(这是可以为精灵指定源矩形的主要原因。)
(与往常一样:这是有关性能优化的建议。因此,在投入精力进行优化之前,您应该衡量并了解游戏的性能以及受到的限制。)
根据MSDN论坛上的一篇文章,XNA框架不执行平截锥体剔除:
XNA框架不会为您做任何平截头寸的选择-它不能因为它不知道任何最终结果的线索。所有转换都在GPU上完成,并且可以是自定义着色器。
http://xboxforums.create.msdn.com/forums/p/22763/121897.aspx
这篇文章继续说,如果您的场景中有很多对象,那么值得自己动手制作。
几年来,我一直在XNA中开发过程体素地形引擎。在大多数帧中,引擎实际上在变换成千上万个四边形。在我的分析中,我发现视锥和遮挡剔除可以提高性能。
XNA HiDef配置文件(不是Reach)具有OcclusionQuery类,该类用于执行遮挡剔除。遮挡剔除会从视口中删除那些被其他四边形隐藏起来的四边形。
您还应该考虑的另一件事是生成和镶嵌。
因此,是的,当您要转换的每个帧中有大量的四边形时,您需要仔细考虑如何应用剔除和线程化技术来通过减少流向gpu着色器的流量来保持帧速率。