遮挡剔除
视锥回答的是它在不在相机前面。而在建筑内部、城镇或峡谷里,通过了这一问的东西大多
仍然看不见:有一堵墙挡着。Occluder 让你说出哪些盒子是视线穿不过去的,渲染器
随后就不再收集站在它后面的东西。
world.insert(wall, Occluder, { halfExtents: { x: 400, y: 300, z: 20 } });组件只有这些。它改变的是一帧的代价,而绝不是它画出来的东西 —— 有遮挡体和没有 遮挡体,两张图是同样的像素。
盒子是创作出来的,而且它要在墙的里面
Section titled “盒子是创作出来的,而且它要在墙的里面”遮挡体不从旁边的几何体推导出来,理由值得记住:网格的包围盒包住网格。柱子、拱门、 石头的包围盒会把四角的空气也算进去,而站在那片空气里的东西就会在玩家明明看得见它的 时候停止绘制。
所以规则是反过来的:
怎么摆:
halfExtents是世界单位,从实体的位置量起,并随实体的旋转转动。缩放不读, 和引擎里其它所有 extent 一致。- 编辑器会在视口里画出这个盒子,所以你可以对着它所在的那堵墙调大小。
- 它可以挂在墙自己的实体上,也可以挂在一个空实体上 —— 由很多网格拼成的一栋楼,通常 要的是一个大盒子,而不是每个网格一个。
它剔什么,不剔什么
Section titled “它剔什么,不剔什么”只剔深度测试本来也会挡掉的那些绘制。一个不做深度测试的绘制会盖在它前面的墙上面, 剔掉它就等于抹掉了这一帧真的画出来的东西 —— 所以精灵、UI、文本,以及材质关掉了深度 测试的任何表面,都不会被遮挡体拒绝。
它也是某个相机的答案,不是场景的答案:
- 一帧里的两个相机各问各的遮挡体。
- 阴影不被它剔除。 玩家看不见的东西照样投影;因为相机看不见它就丢掉一个投影体, 会把它在地上的影子一起带走。
- 相机站在里面的遮挡体会被忽略,而不是宣布整个视野都被挡住了。
怎么读它做了什么
Section titled “怎么读它做了什么”Profiler 里三个计数器,各回答一个不同的问题:
| 计数器 | 说的是 |
|---|---|
render.cull.occluders |
这个视图采纳了多少个盒子 |
render.cull.occluded |
遮挡体拒绝了多少个可渲染物 |
render.culled |
所有剔除,含视锥的那部分 |
遮挡体失效时,前两个数会说出来:盒子数为零说明它们根本没被采纳(转到近平面后面去了, 或者尺寸被编辑成了零);盒子采纳了而 occluded 为零,说明它们前面本来就没挡住什么。
它能claim到多大
Section titled “它能claim到多大”这个判断跑在一张小网格上(横向约为视野的六十四分之一),而一个盒子只能claim它整格 盖满的那些格子。有两条值得据此设计:
- 小于屏幕约 2% 的遮挡体什么都挡不住。付得起的是大形体:墙、楼层之间的地板、建筑、崖壁。
- 被两堵中间有缝的墙合起来挡住的物体,仍然会被绘制。每个盒子只为自己回答。
Occluder 说的是什么挡在路上。它不卸载任何东西 —— 那是流送;
它也不减少绘制的几何量 —— 那是 LODGroup。
三者是可以叠加的:流送决定什么存在,遮挡决定什么被收集,LOD 决定活下来的那些花多少几何。