3D性能和局限性

介绍

Godot遵循平衡的性能理念。在性能世界中,总会有一些折衷,其中包括可用性和灵活性的交易速度。一些实际例子如下:

  • 大量高效地渲染对象很容易,但当必须渲染大型场景时,可能会变得效率低下。要解决这一问题,必须在渲染中添加可见性计算,这会降低渲染效率,但同时渲染的对象更少,因此总体效率会提高。

  • 为需要渲染的每个对象配置每个材质的属性也很慢。为了解决这个问题,对象按材质排序以降低成本,但同时排序也有成本。

  • 在三维物理中,也会发生类似的情况。处理大量物理对象(如SAP)的最佳算法在插入/移除对象和光线投射时速度较慢。允许快速插入和删除以及光线投射的算法将无法处理那么多活动对象。

还有很多这样的例子!游戏引擎在本质上力求是通用的,所以平衡算法总是比在某些情况下可能快而在其他情况下可能慢的算法更受欢迎。或者快速但使可用性更困难的算法。

Godot并不是一个例外,虽然它的设计目的是让后端可以换成不同的算法,但是默认的(或者更像是目前唯一的)优先考虑平衡和灵活性而不是性能。

有了这一点,本教程的目的就是解释如何从Godot中获得最大的性能。

致使

3D渲染是最难获得性能的领域之一,因此本节将列出一些技巧。

重用材质球和材质

Godot渲染器与外面有点不同。它的设计目的是尽可能减少GPU状态的变化。 SpatialMaterial 在重用需要类似材质球的材质方面做得很好,但如果使用自定义材质球,请确保尽可能地重用它们。Godot的优先事项如下:

  • 再利用材料 :场景中不同的材质越少,渲染速度越快。如果一个场景中有大量的物体(成百上千个),尝试重复使用这些材料,或者在最坏的情况下使用地图集。

  • 重用明暗器 :如果材质无法重用,至少尝试重新使用明暗器(或具有不同参数但配置相同的空间材质)。

例如,如果一个场景有20000个对象,每个对象有20000种不同的材质,则渲染速度会很慢。如果同一场景有20000个对象,但只使用100个材质,渲染速度会非常快。

像素成本与顶点成本

人们普遍认为,模型中多边形的数量越少,渲染速度越快。这是 真正地 相对的,取决于许多因素。

在现代PC机和控制台上,Vertex成本较低。GPU最初只渲染三角形,因此所有顶点:

  1. 必须由CPU转换(包括剪切)。

  2. 必须从主RAM发送到GPU内存。

现在,所有这些都在GPU中处理,所以性能非常高。3D艺术家通常对多计数性能有错误的感觉,因为3D DCC(如Blender、Max等)需要将几何图形保存在CPU内存中以便进行编辑,从而降低实际性能。事实是,3D引擎渲染的模型比3D DCC显示它们的方式更为优化。

在移动设备上,情况不同。PC和控制台GPU都是蛮力的怪物,它们可以从电网中获取所需的电力。移动GPU仅限于一个小电池,因此它们需要更节能。

为了提高效率,移动GPU试图避免 透支 . 这意味着,屏幕上的同一像素多次被渲染(如中所示,带有照明计算等)。想象一个有几个建筑物的城镇,GPU不知道什么是可见的,什么是隐藏的,直到他们画出来。可能会绘制一个房子,然后在它前面绘制另一个房子(对同一像素渲染两次!).pc gpus通常不太关心这一点,只需在硬件上添加更多像素处理器以提高性能(但这也会增加功耗)。

在移动设备上,拉更多的电源不是一个选择,因此使用了一种称为“基于平铺的渲染”的技术(几乎每个移动硬件都使用它的变体),它将屏幕划分为一个网格。每个单元格保留绘制到其上的三角形列表,并按深度对其排序以最小化 透支 . 这项技术提高了性能并降低了功耗,但会影响顶点性能。因此,可以处理绘图的顶点和三角形更少。

通常情况下,这并不坏,但移动设备上有一个必须避免的角情况,即在屏幕的一小部分内有许多几何图形的小对象。这迫使移动GPU在单个屏幕单元上施加了很大的压力,从而大大降低了性能(因为所有其他单元必须等待它完成才能显示帧)。

为了简短起见,不要担心移动设备上的顶点数量太多,而是避免在屏幕的小部分集中顶点。例如,如果角色、npc、车辆等离得很远(因此看起来很小),请使用较小的详细程度(lod)模型。

必须考虑顶点成本的额外情况是每个顶点都有额外处理的对象,例如:

  • 蒙皮(骨骼动画)

  • 变形(形状键)

  • 顶点照明对象(在移动设备上常见)

纹理压缩

Godot提供在导入时压缩3D模型的纹理(VRAM压缩)。存储时,视频RAM压缩在大小上不如PNG或JPG有效,但在绘制时会极大地提高性能。

这是因为纹理压缩的主要目标是减少内存和GPU之间的带宽。

在3D中,物体的形状更多地依赖于几何图形而不是纹理,因此压缩通常不明显。在2d中,压缩更多地依赖于纹理内部的形状,因此2d压缩产生的伪影更加明显。

作为警告,大多数Android设备不支持透明纹理的纹理压缩(仅不透明),因此请记住这一点。

透明对象

如前所述,godot按材质和明暗器对对象进行排序以提高性能。但是,这不能在透明对象上完成。透明对象从后到前进行渲染,以与工作背后的内容进行混合。因此,请尽量减少透明对象!如果对象有一个具有透明度的小部分,请尝试使该部分成为单独的材质。

详细程度(LOD)

如前所述,在某些情况下,使用顶点较少的对象可以提高性能。Godot有一个简单的系统来改变细节的层次, GeometryInstance 基于对象具有可定义的可见性范围。具有多个不同范围的几何图形实例对象可以用作LOD。

使用实例(多网格)

如果必须在同一位置或附近绘制多个相同的对象,请尝试使用 MultiMesh 相反。multimesh允许以极低的性能成本绘制成千上万的对象,这使它非常适合于羊群、草地、粒子等。

烘焙照明

小灯通常不是性能问题。阴影多一点。一般来说,如果有几盏灯需要影响一个场景,最好烘焙它。 (烘焙光照图 )烘焙还可以通过添加间接光反弹来提高场景质量。

如果在Mobile上工作,建议烘焙到纹理,因为这种方法更快。