[Unity3D 游戏开发] 第九章-静态对象

LightMap、遮挡剔除、Batching、寻路网格、反射探头等。

静态对象

静态对象是Unity提供的一个属性,它可以附加在游戏对象或者Prefab上。它的原理是限制物体在运行中不能发生位移变化,预先生成一些辅助的数据,从而达成一种用内存换时间的优化方式。静态元素的种类很多,如图所示:

  • Lightmap Static : 用来表示接受烘焙光照计算,可烘焙光照贴图。
  • Occluder Static : 表示自身可以被遮挡剔除掉。
  • Batching Static : 表示支持静态合批。
  • Navigation Static : 表示可烘焙寻路网格。
  • Occludee Static :表示自身是否可以遮挡其他元素。
  • Off Mesh Link Generation : 寻路连接不同区域的点,就像角色从山顶跳下来。
  • Reflection Probe Static : 反射探头,就像玻璃反射一样的镜面效果。

Lightmap:

Lightmap技术的原理是将场景中的灯光和物体产生的光照与阴影信息烘焙在一张或者多张Lightmap贴图中,这些物体将不再参与实时光照计算,从而减少了大量的性能开销。它的缺点就是参与烘焙计算的对象在游戏过程中不能发生移动,所以游戏中通常会将物体分为两类,一类是可发生位移变化的,它们使用实时光照计算;另一类是不可发生位移变化的,它们采取预先烘焙Lightmap。

遮挡剔除:

Batching(静态合批):

设置静态合批:

首先需要在Player Settings页面中勾选Static Batching和Dynamic Batching(表示动态合批);接着,在游戏场景中选择需要合批的游戏对象,并选中Batching Static标记,然后运行游戏。Mesh Filter会自动生成一个新的Mesh,这样如果有相同的材质、Shader并且参数一致的话,就会合并DrawCall。

脚本静态合批:

自动的静态合批用起来很方便,但是也有隐患。加入场景非常庞大,那么合并出来的Mesh会非常大,运行游戏之后,只要其中有一小部分出现在摄像机内,那么整个Mesh都需要参与渲染。另外,静态合批的最大顶点数是65535,如果顶点数超过了它,Unity就会自动合并出多个Mesh。我们可以利用脚本来动态设置需要合批在一起的游戏对象。如果使用脚本合并,游戏对象不需要选中Static标记。

1
2
3
4
5
6
7
8
9
10
11
using UnityEngine;

public class Script_09_05 : MonoBehavior
{
public GameObject[] datas;

void Start()
{
StaticBatchingUtility.Combine(datas,gameObject);
}
}

这段代码的含义就是将数组中的游戏对象合并到同一个Root节点下,也就是第二个参数指定的。另外,运行游戏之后,合并过的Mesh对象时不可以发生位移的,但是可以移动它指定的Root节点。

动态合批:

动态合批是全自动的,我们不需要做任何事情,但是它有要求:

  • Mesh的顶点数量需要小于300
  • 如果Shader中使用了顶点位置、法线、UV0、UV1和切线,Mesh的顶点数必须小于180

静态合批的隐患:

静态合批的原理就是自动生成Mesh,但是不同Mesh保存的信息可能是不同的。例如Mesh中可能会保存color和tangent,但是大部分Mesh都是不需要这个信息的,如果静态合批中有一个Mesh包含了这个信息,那么合并以后整个mesh都会带上它,这样无疑会增加一些额外的开销。

寻路网格:

反射探头: