优化 3D 性能

剔除

Godot会自动执行视图视锥剔除, 以防止渲染视口外的物体. 这对于发生在小范围内的游戏来说效果很好, 然而在较大的关卡中, 事情很快就会变得很麻烦.

遮挡剔除

比如走在一个小镇上, 你可能只能看到你所在的街道上的几栋建筑, 以及天空和几只飞过头顶的鸟. 然而就一个天真的渲染器而言, 你仍然可以看到整个小镇. 它不会只渲染你前面的建筑, 它会渲染那后面的街道, 与那条街上的人, 那后面的建筑. 你很快就会遇到这样的情况: 你试图渲染比可见的东西多10倍或100倍的东西.

事情并没有看上去那么糟糕,因为 Z 缓冲区通常允许 GPU 仅完全遮蔽位于前方的物体。这被称为深度预处理,且在使用 Forward+ 或 Compatibility 渲染方法时 Godot 会默认启用。但是,不需要的对象仍然会降低性能。

One way we can potentially reduce the amount to be rendered is to take advantage of occlusion. Godot 4.0 and later offers a new approach to occlusion culling using occluder nodes. See 遮挡剔除 for instructions on setting up occlusion culling in your scene.

备注

在某些情况下,你可能需要调整关卡设计以增加更多遮挡机会。例如,你可能需要添加更多墙壁以防止玩家看得太远,否则会因失去遮挡剔除的机会而降低性能。

透明物体

Godot通过 MaterialShader 对对象进行排序以提高性能. 然而, 这对透明物体来说是不可能的. 透明物体从后往前渲染, 以便与后面的物体混合. 因此, 尽量少使用透明对象 . 如果一个物体有一小部分是透明的, 尽量让这部分成为一个独立的表面, 有自己的材质.

更多信息请参阅 GPU 优化 文档。

细节程度(LOD)

在某些情况下, 特别是在远处, 用简单的版本**代替复杂的几何图形可能是个好主意. 最终用户可能看不出什么区别. 考虑看看远处的大量树木. 有几种策略可以替换不同距离的模型. 你可以使用较低的多边形模型, 或者使用透明度来模拟更复杂的几何体.

Godot 4 提供了多种控制细节层次的方法:

虽然它们可以单独使用,但一起使用时这些方法最有效。例如,你可以设定可见范围来隐藏距离玩家太远而无法注意到的粒子效果。同时,你可以依靠网格LOD来使粒子效果的网格在远处算绘时细节较少。

可见范围也是为远处几何体设定冒充者的好方法(见下文)。

Billboard 和 imposter

使用透明度处理 LOD 的最简单版本是广告牌。例如,你可以使用单个透明四边形来表示远处的一棵树。除非彼此前面有很多棵树,否则这可以非常便宜地渲染。在这种情况下,透明度可能会开始侵蚀填充率(有关填充率的更多信息,请参阅《GPU 优化》)。

另一种方法是不只渲染一棵树, 而是将一些树作为一组来渲染. 如果你能看到一个区域, 但在游戏中不能实际接近它, 这可能是特别有效的.

你可以通过预先渲染对象的不同角度的视图来制作冒牌货. 或者你甚至可以更进一步, 周期性地将一个物体的视图重新渲染到一个纹理上, 作为一个冒牌货使用. 在远处, 你需要将观察者移动相当长的距离, 视角才会发生显著变化. 这可能是复杂的工作, 但可能是值得的, 这取决于你正在制作的项目类型.

使用实例化(MultiMesh)

如果必须在同一地点或附近绘制多个相同的对象, 请尝试使用 MultiMesh 来代替.MultiMesh允许以很小的性能代价来绘制成千上万的对象, 这使得它非常适合用于绘制羊群, 草地, 粒子以及其他任何有成千上万相同对象的地方.

另请参阅《使用 MultiMesh》文档。

烘焙照明

照明对象是最昂贵的渲染操作之一。实时照明、阴影(尤其是多个光源)和全局光照都特别昂贵。对于低功耗的移动设备来说,它们可能简化得太多而无法处理。

考虑使用烘焙照明,尤其是移动设备。这看起来很棒,但缺点是它不是动态的。有时,这是值得做出的权衡。

有关使用烘焙光照贴图的说明,请参阅 使用光照贴图全局照明。为了获得最佳性能,你应该将灯光的烘焙模式设置为Static(静态),而不是默认的Dynamic(动态),因为这将跳过具有烘焙光照的网格上的实时光照。

使用 Static 烘焙模式的灯光的缺点是,它们无法将阴影投射到具有烘焙照明的网格上。这可以使具有室外环境和动态对象的场景看起来平坦。性能和质量之间的良好平衡是 DirectionalLight3D 节点保持 Dynamic,并对大多数(如果不是全部)泛光灯和聚光灯使用 Static

动画和皮肤

在某些平台上,动画和顶点动画(例如蒙皮和变形)可能非常昂贵。你可能需要大幅降低动画模型的多边形数量,或限制任意时间在屏幕上的模型数量。你还可以降低远处或遮挡网格的动画速率,或者如果玩家不太可能注意到动画被停止时完全暂停动画。

VisibleOnScreenEnabler3DVisibleOnScreenNotifier3D 节点可用于此目的。

庞大的世界

如果你要制作大型游戏, 则与小型游戏可能会有所不同.

大型的世界可能需要用碎片建立, 可以在你在世界中移动时按需加载, 这可以防止内存使用失控, 也可以将所需的处理限制在局部区域.

由于大型世界中的浮点错误,渲染和物理也可能出现故障。可以使用 大世界坐标 解决该问题。如果无法使用大型世界坐标,你可以使用一些技术,例如围绕玩家定位世界(而不是相反),或定期移动原点以使事物以 Vector3(0, 0, 0) 为中心。