在某些方面,这是一个相当基本的问题,但很多人(包括我自己)并不真正知道答案。 GPU制造商经常引用数量非常多的数据,各种游戏引擎声称支持的多边形计数之间的差异通常跨越多个数量级,然后仍然严重依赖于许多变量。

意识到这是一个广泛的,几乎是开放式的问题,对此我深表歉意,我只是认为这仍然是一个有价值的问题。

评论

我认为问题不一定是开放性的,但是任何数字答案在12个月内都会出错。

@DanHulme是的,但是达到这种效率的方法保持不变。而且,如果不是这样,我会在其他stackexchange网站上看到需要定期更新答案的问题,所以我认为很好。

这确实是不可能回答的。首先,什么是“实时”(60fps)? 30吗减?其次,答案将因您拥有的GPU和渲染的分辨率而异。第三,答案将有很大不同,具体取决于渲染工作原理的细节。对场景复杂性的限制不仅限于本身的多边形数量,而且还涉及诸如绘制调用,状态更改,渲染通道等之类的因素,这些因素受引擎工作方式,艺术家如何构建对象的影响。场景等等...

@Llamageddon考虑到您的评论,我不太确定您的实际要求。一方面,您的问题标题非常清楚(最大几何图形和操作方法),但是正如Nathan所指出的,这是不可能回答的。另一方面,您在评论中说您想知道如何最小化每帧成本。这是一个非常广泛的问题,因为您可以改善/优化着色器,场景图,模型,纹理,API的使用,而仅仅是改善渲染功能的所有部分。您可能会撰写有关此书的完整书籍(如果尚未由某人完成)。

这有点晚了,但是在Blender中,您可以看到带有24.000.000顶点的STATIC网格。我可以用40 FPS旋转它。我认为现代图形卡可以完成的工作真是太神奇了。

#1 楼

我认为实时是超越交互的一切,这已被普遍接受。交互式被定义为“响应输入,但由于动画看起来像锯齿状而并不流畅”。
因此,实时性将取决于一个人需要表现的运动速度。电影院以24 FPS的速度投影,并且在许多情况下都足够实时。

然后通过检查自己即可轻松验证一台机器可以处理多少个多边形。只需创建一个VBO补丁作为一个简单的测试和一个FPS计数器,许多DirectX或OpenGL示例将为您提供此基准的理想测试平台。

您会发现您是否拥有高端图形卡,您可以实时显示约一百万个多边形。但是,正如您所说的,引擎将不会轻易获得支持,因为现实世界中的场景数据会导致大量与多边形计数无关的性能消耗。

您拥有:


填充率


纹理采样
ROP输出


绘制调用
渲染目标开关
/>缓冲区更新(均匀或其他)
画图
着色器复杂度
管道复杂度(是否使用了任何反馈?迭代几何着色还是遮挡?)与CPU同步点(像素回读? )
多边形丰富度

取决于特定图形卡的弱点和强点,这些点中的一个或另一个将成为瓶颈。并不是您可以肯定地说“那就是那个”。

编辑:

我想补充一点,一个人不能使用一个特定的GFlops规格图并将其线性映射到多边形推入能力。由于多边形处理必须经过图形管线中的顺序瓶颈,因此在此进行了详细说明:https://fgiesen.wordpress.com/2011/07/03/a-trip-through-the-graphics -pipeline-2011-part-3 /
TLDR:在原始组装之前,顶点必须适合一个小的缓存,这本来就是一个顺序的事情(顶点缓冲区的顺序很重要)。

如果将GeForce 7800(已经使用9年了?)与今年的980相比较,似乎每秒可以执行的操作数量增加了1000倍。但是您可以打赌,多边形的推入速度不会快一千倍(按这个简单的度量标准,每秒推入约2000亿个多边形)。

EDIT2:

要回答问题“如何优化引擎”,例如“不会在状态切换和其他开销方面损失太多效率”。
这个问题与引擎本身一样古老。并且随着历史的发展变得越来越复杂。

在现实世界中,典型的场景数据将包含许多材质,许多纹理,许多不同的着色器,许多渲染目标和通道以及许多顶点缓冲区等。我使用过的一种引擎使用了数据包的概念:

一个绘画包可以通过一次绘制调用呈现。
它包含以下标识符:


顶点缓冲区
索引缓冲区
相机(赋予通过和渲染目标)
材质ID(赋予着色器,纹理和UBO)
与眼睛的距离
是可见

因此,每帧的第一步是使用带有优先考虑可见性的运算符的排序功能对数据包列表进行快速排序,然后依次传递,材质,几何图形和最终距离

靠近物体的绘制是优先考虑的,以最大程度地尽早进行Z剔除。
通过是固定步骤,因此我们别无选择,只能尊重它们。
材料是最昂贵的东西。渲染目标后进行状态切换。

即使在不同的材质ID之间,也可以使用启发式标准进行子排序,以减少着色器更改的数量(在材质状态切换操作中最昂贵),其次是纹理绑定更改。

完成所有这些排序之后,如果认为必要,可以应用大型纹理,虚拟纹理和无属性渲染(链接)。

关于引擎API的另一件事是推迟发出客户端所需的状态设置命令。如果客户端请求“设置相机0”,则最好仅存储此请求,并且如果以后客户端调用“设置相机1”,但之间没有其他命令,则引擎可以检测到第一个命令的无用性并将其丢弃。这是冗余消除,这可以通过使用“完全保留”的范例来实现。与“立即”范例相反,后者只是本地API的包装,并按客户端代码的顺序正确地发出命令。 (例如:virtrev)

最后,对于现代硬件而言,(非常昂贵的)(开发),但可能具有很高回报的步骤是将API切换为metal / mantle / vulkan / DX12样式,手工准备渲染命令。

准备渲染命令的引擎会创建一个缓冲区,其中包含一个“命令列表”,该缓冲区在每个帧处都会被覆盖。

通常会有“预算”帧的概念,游戏负担得起。您需要在16毫秒内完成所有操作,因此您可以清楚地划分GPU时间:“ lightpre pass通过2 ms”,“ material pass通过4 ms”,“间接照明6 ms”,“后处理4 ms” ...

评论


$ \ begingroup $
对我来说,一百万似乎有点低。
$ \ endgroup $
– joojaa
2015年12月14日9:00

$ \ begingroup $
只需拿出卡能达到的MPoly / s即可,这就是它可以渲染100万张的FPS。我刚刚记得在ATI4800HD上进行地形渲染的实验。如果您采用此列表,则它们不会从统一体系结构时代开始就提供Vertices的信息。en.wikipedia.org/wiki/List_of_Nvidia_graphics_processing_units但是使用10年的硬件似乎为100万个三角形广告了40 FPS。 + c.f.编辑我的答案
$ \ endgroup $
–v.oddou
15年12月14日在9:30

$ \ begingroup $
@ v.oddou是的,但是要达到这个数字,您需要对几何进行批处理或在动态场景下实例化,这就是我要问的问题。如何不使自己成为2%的硬件瓶颈。
$ \ endgroup $
–拉马吉登
15年12月14日在13:49

$ \ begingroup $
@Llamageddon aaah,我知道,这的确是一个问题。让我看看我能说些什么。 (编辑2)
$ \ endgroup $
–v.oddou
2015年12月15日下午1:47

$ \ begingroup $
深度解答!我已经以用户而不是主持人的身份进行了一些小的编辑。如果它们与您的意图不符,请随意回滚任何/全部。
$ \ endgroup $
–trichoplax
15年12月17日在12:50