优化场景以提高WebGL性能 - Soft8Soft
Description: 这里是我们推荐的一些用于优化交互式WebGL应用的实用技巧。这些技术经过项目实战验证，非常有效。

# 优化场景以提高WebGL性能

这里是我们推荐的一些用于优化交互式网页应用的实用技巧。这些技术经过项目实战验证，非常有效。本章节内容主要基于Soft8Soft在Verge3Day Europe2019会议上的 演讲文稿 。

- 几何体/网格
- 法线贴图
- 纹理化
- 顶点色
- 着色器数量
- 绘制调用
- HDR照明
- 阴影
- 另请参阅

#

## 几何体/网格

几何体构成了模型的主要形状，是模型的根基。若要获得更平滑的反射和更快的渲染，应尽量遵守网格规则。您应该在一开始就规划好场景所拥有的细节层次，并在建模时始终坚持这一点。

在建模折痕/褶皱时，尽量选择平滑组而非添加更多的多边形。

在处理圆柱形时，尽量减少其中心的多边形数量。

不要在用户无论如何都看不到的地方增加额外的细节加重模型负担。如下图所示，用突出显示的橙色线定义模型细节程度，用作整体建模参考。

#

## 法线贴图

优化WebGL性能的一种常见方法，通过烘焙从高多边形模型到低多边形模型的法线贴图，来减少多边形的数量。

然而，由于8比特图像的精度有限，法线贴图可能会产生可见的伪影。下面是一些常见但并不实际的解决方案：第一种方法，使用更高精度的图像将生成更重的场景资产；第二种方法（平滑组+法线贴图）相当耗时，且也不能保证得到干净的结果；第三种方法（添加噪点）在某些情况下可用：如果您有相当粗糙的表面，建议在材质中添加噪点以减少瑕疵。

根据我们的经验，对于有光泽的物体，最好的解决方案是使用带平滑组的中等面多边形，而不使用法线贴图。

最后，下面是一些可能您倾向使用法线贴图而非高精度网格的情况：

- 您的物体由许多不同的表面组成；
- 您有一个不会产生清晰伪影的粗糙表面；
- 您的物体很远或很小，用户不会注意到任何细节效果。

#

## 纹理化

这里是一组PBR渲染管线中常用的典型纹理。

如您所见，大多数都是黑白图片。所以您可以将黑白纹理组合到单个图像的RGBA通道里，每个图像最多可包含4张贴图。

如果您只有一个黑白纹理，可以打包到任何现有的RBG纹理的alpha通道中。如果没有可供合并的纹理，建议将该黑白纹理转换为jpg格式，使用95%的压缩比并启用灰度模式。

另一种减少纹理大小的方法是优化UV空间。UV展开越紧凑，图像使用纹理空间的效率就越高。因此，您可以用更小的图像而不担心质量损失。

#

## 顶点色

使用顶点颜色代替图像纹理也可以加快加载速度并有效提高WebGL应用整体性能。但这样做是以消耗额外的边为代价的，为了分离不同的顶点颜色，您必须将这些边添加到模型中。

您也可以使用顶点色来定义粗糙度、金属度、镜面及任何其他参数。从下图您可看到仅使用顶点色的材质示例。

#

## 着色器数量

在场景中使用较少的材质/着色器非常有好处。WebGL中对着色器的处理会导致加载时间延长，在Windows系统上尤为明显。因此，如果您的着色器较少，则引擎在渲染时将花费更少的时间在它们之间进行切换，从而提高了性能。

如果您的场景中有仅纹理不同的相似材质，则可以仅使用一种材质，并在运行时环境中加载或交换纹理。为此，您可以使用 replace texture（替换纹理） 拼图或使用JavaScript来完成设置。这样不仅将减少使用着色器的数量，还将减少在应用启动时所加载图像的数量。

这是一个此类优化的例子。所有这些轮胎仅由一种材质表现，并通过交换其纹理进行配置。

为了减少着色器的数量，可以将2种或更多种简单材质组合为一种较大的材质。如果您打算在这些材质之间切换（例如，您正在制作配置器应用），则此技术特别有效。以这种方式应用可更快地运行，并且还可以进行动画过渡。

#

## 绘制调用

此外，还有一个非常重要的方面，绘制调用。绘制调用（DrawCall），是指CPU对图形绘制接口的调用，通过调用图形库（DirectX/OpenGL）接口，命令GPU进行渲染操作。绘制调用的数量是对性能影响的一个重要方面。可以通过 print performance info(打印性能信息) 拼图输出的Geometry Buffer（几何缓存）部分来获取数据。如果每个对象只分配一种材质，则此数据大致对应了单独对象的数量，而多材质对象则需要更多的绘制调用来渲染。

因此，在可能的情况下，应尽量连接网格，并使用较少的独立材质，以减少绘制调用的次数并提高性能。

如果有已设置动画的对象，您仍然可以将各部分结合在一起，并使用骨骼进行动画控制。这有时甚至比为单独的对象设置动画时更为方便。

#

## HDR照明

如果只使用HDR图像而不使用任何光源来照亮场景，亦可以大幅度提高性能。HDR文件的体积有的甚至小于1 Mb。

#

## 阴影

只在有助于更好地展现物体时才使用动态阴影。如下图，工业机器人案例中使用的动态阴影强调了机器的模型形状。因为允许旋转模型，所以阴影中的任何细节都会直接显示。另一个案例中，电动滑板车的阴影则会隐藏掉很多细节。

如果对象在应用中不移动，则可以烘焙阴影和环境光遮蔽贴图，并将其置于对象下的平面上。

#

## 另请参阅

请查看 性能瓶颈 章节了解如何发现应用中的性能瓶颈，以及 资产压缩 章节，了解如何使场景更加紧凑。

## 遇到问题？

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