查找Verge3D性能瓶颈 - Soft8Soft
Description: 了解如何发现并解决Verge3D应用中的性能瓶颈。

# 查找Verge3D性能瓶颈

- 简介
- 检查FPS
- 性能概况
- 常见的渲染性能瓶颈
  - 复杂材质
  - 后期处理
  - 阴影
  - 几何形状太多
  - 迟钝的图像照明
  - 灯光太多
  - 渲染调用太多
- 场景加载时间
  - 较大的二进制数据或纹理
  - 太多或太复杂的材质
- GPU内存使用情况
  - 大尺寸纹理
  - 大型几何缓存
- 另请参阅

#

## 简介

您发布的网页应用将面向海量的互联网用户，因此基于Verge3D的应用必须具备良好的性能表现。例如，某些支持WebGL的设备的工作性能可能比您的预期差很多：

- 比较典型的，如使用集成显卡（Intel，AMD APU Graphics）的中低端笔记本等。
- 老式智能手机或平板电脑。
- 移动VR设备，如Oculus Go或Oculus Quest。为了防止晕动症，这些设备必须以适当的帧率（60,72,甚至90 FPS）进行渲染。
- 使用电池供电的设备。GPU长时间高负荷会迅速耗尽移动设备的电池电量。

为了有效优化，即尽量不降低应用质量，您应该了解基本的 资产优化技术 并且能够在应用中找出导致加载和渲染缓慢的原因。这些被称为 性能瓶颈。

#

## 检查FPS

FPS（每秒帧数，或帧率）是代表应用的渲染时间和用户体验的一个至关重要的量：

- < 20 ：应用会非常卡顿，几乎无法使用。
- 20-40 ：反应迟缓，但可以接受。
- 40-60 ：足够好了。
- 60 ：桌面和移动浏览器上的理想帧率。
- > 60 ：为VR头戴式设备做开发的目标帧率。

Verge3D自带内置的FPS计数器。您可以通过以下方式启用它：

- 快速按下 ~, ~, ~（连按3次波浪键），然后从 Service Tools 菜单中选择 F。如果您的键盘上没有波浪键，请使用最左上角的键代替。
- 使用JavaScript的API方法 showFPS() 。

一旦激活，您就可以在应用的画布左上角的小面板上看到当前的FPS值（帧率范围和历史）：

为获得合理的值，您应该在您拥有的最慢/最旧的设备上测量FPS。此外，大多数浏览器不允许帧速率大于60赫兹（目的是改善帧同步率，节省电池寿命，降低风扇噪音等）。

#

## 性能概况

Verge3D附带了一个功能，可以实时生成性能概况统计。您可以快速了解应用中的性能发生了什么，以及应该做些什么来提高性能。要生成此类分析报告,可以使用以下方法之一：

- 快速按键盘上的 ~, ~, ~（连按3次波浪键），然后从 Service Tools 菜单中选择 P (Verge3D 3.2+）。如果您的键盘上没有波浪键，请使用最左上角的键代替。
- 使用 print performance info（打印性能信息） 拼图。
- 使用JavaScript的API方法 printPerformanceInfo() 。

Verge3D收集配置文件数据时，请至少等待1秒，然后打开浏览器 控制台。在打开的控制台窗口中检查输出的字符串：

`--- Verge3D Performance Profile (1s) ---`

以下是收集到的性能信息：

下面是您可以从生成的性能概况报告中查询的内容：

Scene Loading Time
  加载应用主场景。参见 下文 了解如何加快加载。
Asset Compression
  显示是否启用了资产压缩。
Shader Compilations
  显示启动和运行场景所需的着色器编译次数。
FPS
  渲染帧速率。这与FPS计数器报告的值相同。
Render Calls
  每帧的渲染调用数量。这是一个重要数值，显示在一帧期间执行了多少绘制操作，代表了场景中不同材质的数量+各种补充渲染调用（如阴影、后期处理等）之和。
Triangles Rendered
  每帧渲染了多少个三角形。请参阅下面有关此值的更多信息。
Geometry Buffers
  应用使用了多少几何缓存
HDR Rendering
  HDR渲染是否启用: on 或 off。
Order-Independent Transparency
  顺序无关透明度功能是否开启：on 或 off。
Viewport Resolution
  渲染视口的分辨率，即当前网页中3D Canvas的分辨率。
Pixel Ratio
  当前（由渲染器使用）和设备（本机）的像素比率。
Image-Based Lighting
  IBL照明的类型及IBL立方体贴图的切片大小。
Lights
  场景中的灯光数。
Reflection Probes
  场景中使用的立方体反射与平面反射光照探头的数量。
Post-Processing
  场景后期处理过程（按渲染顺序）。
Shadow Map
  阴影贴图参数：过滤类型；已渲染阴影贴图的数量；阴影贴图的分辨率。
Materials and Shaders
  已渲染材质和着色器的列表。列表各项包含了以下信息：材质名称，着色器名称，和每帧渲染时间（以毫秒为单位）。
Total Render Time
  渲染场景所用的总时间（以毫秒为单位）。
Textures & Render Buffers
  纹理和渲染缓存统计（分辨率）。纹理列印在列表的顶部（前缀为Texture)，而渲染缓存列印在列表的底部（前缀为RenderTarget)。纹理格式信息： RGBA 用于未压缩纹理，使用 RGBA_[METHOD] 进行纹理压缩。

要快速定位性能问题，您首先应注意被标记为红色的行。例如，在下图中的阴影贴图似乎太大（4K），这可能会导致渲染速度变慢。

#

## 常见的渲染性能瓶颈

以下是限制帧率的最常见瓶颈。

#

### 复杂材质

图形硬件每秒可以渲染有限数量的像素。在大多数情况下，若素材使用了冗长和复杂的像素着色器（又名片段着色器），将不能渲染更多内容，这需要大量的GPU处理能力。

您可以通过减小或增大浏览器窗口大小来简单地检测像素性能受限的情况。如果您的帧速率(FPS)在您减小尺寸时大幅增长，您就出现了这样的情况。

提高性能最直接的方法是简化材质。请关注 performance profile 顶部的 Materials and Shaders 列表。

在许多情况下，材质性能的问题是由于着色节点迟钝而发生的。请参阅 Blender, 3ds Max 或 Maya 的材质性能小节。

属性设置像素比 < 1，也可以解决着色器性能受限的问题 set screen scale（设置屏幕比例） 拼图。但这会严重降低应用的质量表现，仅作为最后的备用解决方案。

#

### 后期处理

以下几种后期处理效果会显著降低应用的性能：

- 屏幕空间折射和反射（参见此 拼图）。
- 环境遮蔽（参见 Blender / Max / Maya 页)。
- 景深（请参见此 拼图）。

#

### 阴影

复杂的阴影算法与较大尺寸的深度阴影贴图也会降低渲染速度。

1. 如果您的场景中有多个灯光，为亮度最低的那一个禁用阴影。
2. 在大多数情况下, 点光源 的阴影比 聚光灯 阴影或 太阳光/平行光 阴影需要更多的计算。
3. 减小阴影贴图大小（请参见 Blender, 3ds Max, Maya）。
4. 切换到性能要求较低的阴影过滤算法（请参见 Blender, 3ds Max, Maya）。

#

### 几何形状太多

过于复杂的几何形状也会影响您的渲染性能。我们建议每个模型使用不超过十万个三角面，或者每个整个场景不超过一百万个三角面。

#

### 迟钝的图像照明

在Verge3D中，您可以在以下几方面对环境照明进行性能调整：

1. 减小阴影贴图大小（请参见 Blender, 3ds Max, Maya）。我们建议在大多数情况下使用256像素的立方体贴图。
2. 切换到性能更高效的环境模式（请参见 Blender, 3ds Max, Maya）。

#

### 灯光太多

过度的光线计算增加了着色器的复杂性。尽量减少它们的数量或切换到 IBL-only 照明。

#

### 渲染调用太多

成百上千的渲染调用极大地加重了CPU消耗。因此，您应该将该值保持在尽可能低的水平。在大多数情况下，我们建议您将渲染调用的数量保持在100以下。

如果您用相同的材质渲染许多静态物体，可以通过使用 batch geometry(几何图形批处理) 拼图来显著提高效果。

#

## 场景加载时间

另一个需要注意的是场景加载时间。用户不会喜欢加载时间太久的应用。

以下是最常见的导致应用加载速度减慢的瓶颈。

#

### 较大的二进制数据或纹理

因为应用资产是通过网络传输的，所以您应该尽量降低其大小。在浏览器 控制台中访问网络检查工具，有助于了解怎样进行资产优化。点击 Network 选项卡并刷新页面。

有关如何使用此功能,请查看浏览器文档：Chrome, Firefox, Safari。

按大小对资源进行排序，找到加载最慢的资源。多数情况下，这些资产可分为两类：

1. Verge3D Binary：以 *.bin 或 *.bin.xz 为扩展名——包含了场景中的几何图形、变形和动画。启用资产压缩可以显著减小此文件尺寸，建议在应用中始终 启用 此选项。
2. Textures：以 *.jpg、*.png 或 *.hdr 为扩展名——请参阅 这里 有关如何优化纹理的更多信息。

还有两种简单粗暴却高效优化纹理方法：

1. 将纹理的尺寸缩小2倍（例如2048x2048到1024x1024甚至512x512)。
2. 将所有PNG纹理转换为JPEG（即使是法线贴图）。

#

### 太多或太复杂的材质

除少数例外，场景上的每个素材都需要编译一对叫做着色器的特殊程序： 顶点着色器 和 片段着色器（又名像素着色器） ，着色器是在GPU上执行的一个特殊程序，用来计算各种渲染实体，如顶点位置、纹理、光照、反射、折射等。

着色器编译是一项计算量很大的任务，每次加载应用时都要执行。如果您的场景有很多材质，着色器编译时间会显著增加。

所以应用所使用的着色器越少，加载速度就越快。此外，着色器是由WebGL缓存的，因此如果着色器被多个对象使用，则只编译一次。

因此，为了快速加载，使用尽可能少的唯一着色器是很重要的。实现这一点的一个可能方法是启用glTF兼容性标志，这a）大大简化了着色器，以便更快地编译和工作；b）标准化了着色器，以实现更有效的缓存。

使用与glTF兼容的着色器的明显缺点是，对于实现所需的图形效果而言，它们可能过于简单化。因此，在实时计算的图像效果中，您需要在质量和性能之间取得平衡。

#

## GPU内存使用情况

使用过多的GPU内存会显著降低性能，甚至会使应用崩溃。以下是消耗GPU内存过多的情形。

#

### 大尺寸纹理

例如，一个大小为4096x4096的纹理将占用了接近90 Mb的显存。请在 performance profile中 Textures & Render Buffers 中查看应用中用到的所有纹理的尺寸数据。

请参阅 这里 有关如何计算纹理内存使用的更多信息。

请参阅 纹理压缩 章节， 了解如何减少纹理所消耗的内存。

#

1

### 后期处理过程太多

大多数后期处理效果需要额外的渲染缓存，这会消耗GPU内存。在 performance profile 中 Textures & Render Buffers 列表底部查看所有的渲染缓存。

#

### 大型几何缓存

具有大量三角面的网格需要很大的几何缓存，因此需要消耗大量的显存来存储它们。

#

## 另请参阅

查看 优化技巧 部分，了解更多资产优化方法。

## 遇到问题？

欢迎您随时在 论坛上提问！您还可以加入中文用户社区QQ群(171678760)，在线寻求帮助。