Version: 2019.1
创建尺寸大小的效果
动态分辨率

遮挡剔除

当对象被其他对象阻挡(遮挡)而不能被摄像机所看到时,遮挡剔除 (Occlusion Culling) 功能会禁用对象的渲染。这种情况不会自动发生在 3D 计算机图形中,因为在大多数时间,距离摄像机最远的对象都是先绘制的,而较近的对象则在先前对象的基础上绘制(这称为“过度绘制 (Overdraw)”)。遮挡剔除与视锥体剔除 (Frustum Culling) 不同。视锥体剔除仅禁用摄像机视野之外的对象的渲染器,而不会禁用由过度绘制隐藏起来的任何对象的渲染器。请注意,使用遮挡剔除时,仍然会受益于视锥体剔除。

迷宫般的室内关卡。此常规 Scene 视图显示了所有可见的游戏对象。
迷宫般的室内关卡。此常规 Scene 视图显示了所有可见的游戏对象。
常规视锥体剔除仅渲染摄像机视野内的对象。这是自动始终执行的原则。
常规视锥体剔除仅渲染摄像机视野内的对象。这是自动始终执行的原则。
如果有对象被更近的对象完全遮挡,则遮挡剔除可进一步从摄像机渲染工作中移除这些被遮挡的对象。
如果有对象被更近的对象完全遮挡,则遮挡剔除可进一步从摄像机渲染工作中移除这些被遮挡的对象。

遮挡剔除过程将使用虚拟摄像机在场景中移动,进而构建潜在可见对象集的层级视图。每个摄像机在运行时都会使用此数据来识别可见和不可见的对象。凭借此信息,Unity 将确保只发送可见对象进行渲染。这样可减少绘制调用次数并提高游戏性能。

遮挡剔除的数据由单元格组成。每个单元格是从整个场景包围体上细分而来。具体地来说,这些单元格形成一个二叉树。遮挡剔除使用两个树,一个用于视图单元格(静态对象),另一个用于目标单元格(移动对象)。视图单元格映射到一个定义可见静态对象的索引列表,从而为静态对象提供更准确的剔除结果。

在创建对象时记住这一点很重要,因为您需要在对象大小和单元格大小之间取得良好的平衡。理想情况下,单元格与对象相比不应该太小,但同样,对象不应该覆盖大量单元格。有时,可通过将大型对象分成更小的碎片来改善剔除。但是,您仍然可以将小对象合并在一起以减少绘制调用,只要它们都属于同一个单元格,就不会影响遮挡剔除。

您可以使用“过度绘制”场景渲染模式来查看正在发生的过度绘制量,并可使用 Game 视图中的统计信息面板查看正在渲染的三角形、顶点和批次的数量。下面是应用遮挡剔除之前和之后的比较。

注意在过度绘制的 Scene 视图中,由于渲染了可见墙壁背后的很多房间,因此过度绘制的密度很高。这些对象在 Game 视图中不可见,但是仍然要用时间来渲染它们。
注意在过度绘制的 Scene 视图中,由于渲染了可见墙壁背后的很多房间,因此过度绘制的密度很高。这些对象在 Game 视图中不可见,但是仍然要用时间来渲染它们。
应用遮挡剔除后,不会渲染远处房间,过渡绘制的密度大幅降低,渲染的三角形和批次数量急剧下降,Game 视图的外观没有任何变化。
应用遮挡剔除后,不会渲染远处房间,过渡绘制的密度大幅降低,渲染的三角形和批次数量急剧下降,Game 视图的外观没有任何变化。

设置遮挡剔除

为了使用遮挡剔除,需要进行一些手动设置。首先,关卡几何体必须分成尺寸合理的碎片。将关卡布置到大型对象旁(例如墙壁、建筑物等)彼此遮挡且界限分明的小型区域中,也很有帮助。此处的思路是基于遮挡数据开启或关闭每个单独的网格。因此,如果您有一个包含房间所有家具的对象,则整套家具将全部剔除或全部不剔除。这种方法并不像使每件家具拥有自己的网格(因此每个家具都可以根据摄像机的视点单独剔除)那样合理。

您需要在 Inspector 中把纳入遮挡计算的所有场景对象标记为 Occluder Static。执行此操作最快的方法是多选要包含在遮挡计算中的对象,然后将它们标记为 Occluder StaticOccludee Static

标记要进行遮挡的对象
标记要进行遮挡的对象

何时应使用 Occludee Static__?不会产生遮挡的完全透明或半透明对象,以及不太可能遮挡其他对象的小型对象应标记为__被遮挡物 (Occludee) 而不是__遮挡物 (Occluder)__。这意味着,它们将被其他对象遮挡,但本身不会被视为遮挡物,这样将有助于减少计算。

使用 LOD 组时,只有基本级别对象 (LOD0) 可用作遮挡物。

遮挡剔除窗口

对于大多数处理遮挡剔除的操作,都应该使用遮挡剔除窗口 (Window > Rendering > Occlusion Culling)

在遮挡剔除窗口中,可使用遮挡物网格和遮挡区域 (Occlusion Areas)

如果您处于__遮挡剔除窗口__的 Object 选项卡中,并在场景中选择了网格渲染器,您就可以修改相关的静止标记:

网格渲染器的遮挡剔除窗口
网格渲染器的遮挡剔除窗口

如果您处于__遮挡剔除窗口__的 Object 选项卡中,并选择了遮挡区域 (Occlusion Area),您就可以使用相关的 OcclusionArea 属性(有关更多详细信息,请转到遮挡区域部分)

遮挡区域的遮挡剔除窗口
遮挡区域的遮挡剔除窗口

注意:默认情况下,如果不创建任何遮挡区域,遮挡剔除将应用于整个场景。

注意:只要摄像机位于遮挡区域之外,就不会应用遮挡剔除。设置遮挡区域来覆盖摄像机可能出现的位置非常重要的,但如果将这些区域设置得过大,烘焙过程中就会产生额外成本。

遮挡剔除 - Bake

遮挡剔除检视面板 Bake 选项卡。
遮挡剔除检视面板 Bake 选项卡。

遮挡剔除烘焙窗口有一个“Set Default Parameters”按钮,允许您将烘焙值重置为 Unity 的默认值。这些值对于许多典型场景很有用,但您可以调整这些值来适应场景的特定内容,这通常可以产生更好的效果。

属性

属性 功能
Smallest Occluder 进行遮挡剔除时用于隐藏其他对象的最小尺寸。任何小于这个尺寸的对象都不会剔除它们所遮挡的对象。例如,当值为 5 时,高于或宽于 5 米的所有对象都将导致它们挡住的对象被剔除(不渲染,从而节省渲染时间)。为此属性选择一个合适的值,在遮挡数据的精度和存储大小之间取得平衡。
Smallest Hole 此值表示摄像机应该看到的几何体之间的最小间隙。此值表示可以穿过孔的对象的直径。如果场景中存在摄像机应该能够看到的小裂缝,则 Smallest Hole 值必须小于间隙的最窄尺寸。
Backface Threshold Unity 的遮挡使用数据大小优化功能,通过测试背面来减少不必要的细节。默认值 100 比较稳妥,绝不会从数据集删除背面。值 5 将基于具有可见背面的位置大幅减少数据。思路是,一般情况下,有效的摄像机位置通常不会看到太多背面;例如,地形底面的视图,或者您应该无法到达的实体对象内的视图。如果阈值低于 100,Unity 将完全从数据集删除这些区域,从而减少遮挡的数据大小。

Bake 选项卡的底部是 Clear 和 Bake 按钮。单击 Bake 按钮可开始生成遮挡剔除数据。生成数据后,可使用 Visualization 选项卡预览和测试遮挡剔除。如果对结果不满意,请单击 Clear 按钮删除以前计算的数据,调整设置,并再次烘焙。

遮挡剔除 - Visualization

遮挡剔除检视面板 Visualization 选项卡。
遮挡剔除检视面板 Visualization 选项卡。

场景中的所有对象都会影响包围体的大小,因此请尽量将它们全部保留在场景的可见边界内。

准备好生成遮挡数据后,单击 Bake 按钮。请记住在 Bake 选项卡中选择 Memory Limit。较低的值可以加快生成速度,但会降低精确度,较高的值将生成更适合发行版的质量。

请记住,构建遮挡数据所需的时间取决于单元格级别、数据大小和您所选择的质量。

处理完成后,您应该可以在查看区域中看到一些彩色立方体。彩色区域是共享相同遮挡数据的区域。

如果要删除遮挡剔除的所有预计算数据,请单击 Clear

遮挡区域

要将遮挡剔除应用于移动对象,必须创建__遮挡区域 (Occlusion Area),然后修改其大小以适合移动对象所在的空间(当然,移动对象不能标记为静态)。可通过将__遮挡区域 (Occlusion Area) 组件添加到空游戏对象来创建遮挡区域(菜单:__Component > Rendering > Occlusion Area__)。

创建__遮挡区域__后,请选中 Is View Volume 复选框以遮挡移动对象。

属性: 功能:
Size 定义遮挡区域的大小。
Center 设置遮挡区域的中心。默认情况下,此设置为 0,0,0,位于盒体的中心。
Is View Volume 定义摄像机的位置。选中此项可遮挡该_遮挡区域_内的静态对象。
移动对象的遮挡区域 (Occlusion Area) 属性。
移动对象的遮挡区域 (Occlusion Area) 属性。

添加遮挡区域后,需要查看它如何将盒体分成单元格。要了解如何计算遮挡区域,请在 Occlusion Culling 预览面板__中 选择 Edit__ 并切换 View 按钮。

测试生成的遮挡

设置遮挡后,可通过启用 Occlusion Culling_(在 Visualize 模式下的 _Occlusion Culling 预览面板__中)并在 Scene 视图中移动__主摄像机__来测试遮挡。

Scene 视图中的 Occlusion View 模式
Scene 视图中的 Occlusion View 模式

当您移动主摄像机时(无论是否处于播放模式下),您将看到各种对象自行禁用。此处要寻找的是遮挡数据是否有任何错误。如果在移动摄像机时看到有对象突然弹入视图,则表示有错误。如果发生这种情况,修复错误的方法为更改分辨率(如果正在使用目标体积),或者移动对象以掩盖错误。要调试遮挡问题,可将主摄像机移动到有问题的位置进行抽样检查。

处理完成后,您应该在查看区域中看到一些彩色立方体。蓝色立方体表示__目标体积__的单元格划分。白色立方体表示__视图体积__的单元格划分。如果参数设置正确,您应该看到一些对象未被渲染。这是因为它们位于摄像机的视锥体之外,或被其他对象遮挡。

遮挡完成后,如果在场景中没有看到任何对象被遮挡,请尝试将对象分成更小的部分,以便能将它们完全包含在单元格内。

创建尺寸大小的效果
动态分辨率