title: unity-遮挡剔除OcclusionCulling
categories: Unity3d
tags: [unity, occlusion, culling, 性能, 优化]
date: 2019-06-04 12:52:38
comments: false
这是一个优化项, 减少看不见物体的绘制
遮挡剔除 与 摄像机的视锥体剔除 不一样, 视锥体剔除只是剔除掉视锥体之外的物体 (gpu硬件实现), 但是还是会把 顶点送入 gpu 中, 还是会经过 vertex 阶段的计算, 而视锥体之内的物体全都会绘制, 但是会有某个物体被遮挡住不需要绘制的情况, 这是时候就可以由 遮挡剔除 进一步优化 (软件实现, 自动).
最终想要的效果就是 看的到的物体 的才 送入gpu中, 看不到的物体 ( 包括 视锥体之外的 和 视锥体之内的但是被遮挡的 ) 的不送入gpu中, 这样既可以减少 cpu 到 gpu 的传输量, 也可以减少 vertex 和 frag 阶段的计算量.
比如 物体a 很大, 物体b 很小, 在很多视角下 a 都会遮挡住 b, 这时候就可以考虑把 a 标记为 Occluder Static (遮挡者), 把 b 标记为 Occludee Static (被遮挡者), 然后烘焙.
我应该在什么时候使用 Occludee Static?透明物体不能遮挡,以及小物件,都不可能阻挡其他的东西,应标记为Occludees,但不遮挡。这意味着它们将被视为能被其他物体遮挡,但不会被视为作为遮挡物自身,这将有助于减少计算量。
遮挡剔除的运行将通过在场景中使用一个虚拟的摄像机来创建一个物体潜在可视性状态(set)的层级。 这些数据可以实时让每个摄像机来确定什么能看见什么看不见。通过这些数据,Unity 将确定只把可以看见的物体送去渲染。这将降低 绘制调用(draw calls) 的数量并增加 游戏的运行效率。
遮挡剔除的数据由单元格(cells)组成, 每个单元格是在整个场景的包围体积的一部分,单元格来自一个二叉树( binary tree),遮挡剔除使用两棵树, 一个给 View Cells (静态物体) ,另一个给 Target Cells (移动物体)。 View Cells 映射到一个定义静态可视物体的索引列表 (精确剔除后的静态物体)。
使用流程
流程和 寻路区域 烘焙有点像.
- 先把 Occlusion 面板调出来. window -> rendering -> occlusion culling
- 设置场景哪些是 遮挡者 (Occluder Static) 和 被遮挡者 (Occludee Static), 有两种方式
- 选中物体, 在 inspector 面板中的 Static 中勾选
- 选中物体, 在 occlusion 面板中的 object 中勾选
- 添加烘焙区域. 如果不添加的话默认是烘焙整个场景. 也有两种方式创建
- 直接右键创建一个 gameobect, 然后挂上 Occlusion Area 组件
- 在 occlusion 面板中, object -> occlusion areas, 点击 create new occlusion area (如果已选中一个 occlusion area 是不会出现这个创建按钮的)
创建完, 调整 Occlusion Area 组件的包围盒
- 点击 occlusion 面板最下面的 bake 按钮进行烘焙. done.
烘焙前后对比
顶点减少