通用优化指南
以下建议有助于提升 PlayCanvas 应用性能。
JavaScript
- 调用
new分配 JavaScript 对象,尤其是向量、矩阵和四元数,会产生可能较昂贵的动态分配。应尽可能在initialize中预分配,在update中复用。动态分配还会触发垃圾回收,可能造成周期性卡顿。
图形渲染:CPU
- 在 PlayCanvas 中,一个网格实例对应一次绘制调用,即绘制图形图元的命令。CPU 将调用提交到 WebGL 时需要开销,因此应尽量减少,尤其是移动端。选中模型资源后,可在 Inspector 中查看其绘制调用。低端移动设备可粗略以 100 到 200 次为目标;高端桌面设备则可能每帧处理数千次仍达到 60 FPS。
- 使用批处理减少绘制调用。创建 Batch Group,并指定给 Render、Model 和 Element 组件,引擎会尝试将其合并为尽可能少的网格实例,提升性能。
- 尽量减少生成的着色器数量。着色器需要按需编译和链接,成本较高,会延迟启动并造成帧率抖动。例如材质 A 有自发光贴图、B 没有,会生成两个着色器;若为 B 设置黑色自发光贴图,两者就可共用。减少场景材质数也有助于减少着色器数量。
- 蒙皮网格每帧会生成精确包围盒,用于相机视锥剔除。计算开销与骨骼数相关,即使角色完全在视锥外仍会执行。可考虑为角色设置自定义 AABB,它是
Render或Model组件的属性。 - 只有预计收益超过可见性计算成本时,才应启用相机视锥剔除。如果场景中所有网格实例始终可见,可禁用此选项。
图形渲染:GPU
- 谨慎启用项目设置中的 Use Device Pixel Ratio。它让应用使用设备原生分辨率,减少像素感,但也增加待填充像素,可能显著降低帧率。可以评估设备能力后在运行时调整,参见调整设备像素比。
- 尽量减少场景中的动态光源。
- 纹理各向异性越高,视觉效果越好,但性能开销也越大,需要权衡。
- 尽可能将多张纹理合并到同一图像。例如将灰度不透明度放到漫反射 alpha 通道,将灰度光泽度放到高光 alpha 通道,从而降低显存占用。
- 后期效果可能很昂贵,启用前应评估像素填充成本。
- 材质启用背面剔除通常比禁用更便宜,因为减少了 GPU 需要填充的像素。新材质默认启用。
图形渲染:CPU 与 GPU
- 对产品配置器等一段时间内画面变化较少的应用,可将
pc.Application#autoRender设为false,仅在移动相机、添加产品部件等画面变化时,通过pc.Application#renderNextFrame请求渲染,降低 CPU 和 GPU 占用。 - 动态光源阴影开销较大,点光源尤甚。每个投射阴影的点光源都需要将场景渲染六次到阴影贴图。
- 尽量减少透明混合网格实例。不透明对象提交后,混合网格才按相机深度从后向前绘制,可能造成同一像素多次填充;由于不能按材质排序,也可能产生大量渲染状态切换。
物理
- 碰撞网格不需要与渲染网格具有相同细节,建议使用更低分辨率的碰撞网格。
- 尽量减少动态刚体,尤其在移动端。