Skip to main content

2. 遮挡剔除如何影响物体

遮挡剔除对静态对象(如地图元素)和动态对象(如玩家和可拾取物品)的处理方式有所不同。遮挡剔除(Occlusion Culling)会分别处理 静态对象(static,如地图)和 动态对象(dynamic,如玩家、可拾取物品),两者的遮挡规则存在差异:

  • 静态对象既可以隐藏其他物体,也可以被其他物体隐藏。(在某些情况下,你可能不希望静态对象同时具备这两种特性。)这些对象的遮挡信息会在运行前被预烘焙,而在运行时无法更改。 既可以遮挡其他对象,也可以被其他对象遮挡(实际开发中,你未必希望静态对象同时具备这两种特性)。它们的遮挡信息会被烘焙到数据中,运行时无法修改。
  • 动态对象则无法隐藏它们背后的物体,但它们可以根据一种粗略的特殊计算而被其他物体隐藏,这种计算会判断它们是否位于某个静态对象之后。 无法遮挡其后方的对象,但会通过 “是否处于静态对象后方” 的粗略计算来判断是否需要隐藏。

Unity 通过检查对象上的静态标志来确定遮挡剔除将会如何影响它们。遮挡剔除考虑了以下三种不同的情况:通过对象的 静态标记(Static flags) 确定遮挡剔除对其的作用规则,核心分为三类标记逻辑:

  • 静态遮挡物。静态遮挡物(Static Occluders)唯一能够遮挡其他物体的静态对象—:唯一能实现遮挡的是不会移动的静态对象 特别是网格渲染器和地形。如果它们被标记为遮挡物— 具体来说,是网格渲染器(Mesh Renderers)和地形(Terrain)。若这些对象被标记为 “遮挡物静态(Occluder Static)”则它们后面的物体会被隐藏。这些遮挡信息会在运行前被预先烘焙。则其后方的对象会被隐藏。这些对象的遮挡信息会被烘焙到遮挡数据中。
  • 静态被遮挡物。静态被遮挡物(Static Occludees)这指的是那些可以被隐藏的静态对象。被遮挡物可以是任何带有渲染器的物体,只要它在运行过程中不移动。:特指可被遮挡的静态对象。任何带有渲染器(Renderer)且不会移动的静态对象,都可标记为 “被遮挡物静态(Occludee Static)”,进而被其他遮挡物隐藏。
  • 动态被遮挡物。动态被遮挡物(Dynamic Occludees)这包括了场景中的其他所有物体。如果启用了“动态遮挡”:涵盖场景中所有未标记为静态被遮挡物的对象。若启用 “动态遮挡(Dynamic Occlusion)” 属性,那么这些物体可以被静态遮挡物根据预先计算的遮挡信息隐藏。这类对象会基于烘焙好的静态遮挡数据,被静态遮挡物隐藏。
注意:动态遮挡剔除的精度低于静态遮挡剔除。实际应用中,通常只有大型实心对象才能有效隐藏动态对象。

需要注意的是,动态遮挡的效果通常不如静态遮挡精确。实际上,只有那些大型的、实心的物体才可能有效地隐藏动态对象。遮挡剔除基于静态批处理(static batching)工作—— 即使对象已纳入静态批处理,Unity 仍可通过遮挡剔除将其隐藏,二者互不冲突。