The following blog post was written by Jasin Bushnaief of Umbra Software to explain the updates to occlusion culling in Unity Pro 4.3.
以下博客文章由Umbra Software的Jasin Bushnaief撰写,解释了Unity Pro 4.3中遮挡剔除的更新。
Unity 4.3 includes a plethora of improvements. One of the completely re-implemented subsystems is occlusion culling. Not only has the interface been simplified and the culling runtime itself revamped, a number of new features have also been added.
Unity 4.3包含大量改进。 完全重新实现的子系统之一是遮挡剔除。 不仅简化了界面,改进了筛选运行时本身,还添加了许多新功能。
In this series of three posts, I’m going to go over how the new occlusion culling system works in Unity 4.3. This first post goes through the basics of how occlusion culling is done and what the basic usage is like with the user interface. The second post focuses on best practices to get the most out of occlusion culling. The third and final post focuses on some common problem scenarios and how to resolve them.
在这三篇系列文章中,我将介绍新的遮挡剔除系统在Unity 4.3中的工作方式。 第一篇文章介绍了如何进行遮挡剔除以及用户界面的基本用法。 第二篇文章重点介绍最佳实践,以最大程度地发挥遮挡剔除的作用。 第三篇也是最后一篇文章重点介绍了一些常见的问题场景以及如何解决它们。
Umbra’s occlusion culling process can be roughly divided into two distinct stages. In the editor, Umbra processes the game scene so that visibility queries can be performed in the game runtime, in the player. So first, Umbra needs to take the game scene as its input and bake it into a lightweight data structure. During the bake, Umbra first voxelizes the scene, then groups the voxels into cells and combines these cells with portals. This data, in addition to a few other important bits is referred to as occlusion data in Unity.
Umbra的遮挡剔除过程可以大致分为两个不同的阶段。 在编辑器中,Umbra处理游戏场景,以便可以在游戏运行时的播放器中执行可见性查询。 因此,首先,Umbra需要将游戏场景作为其输入,并将其烘焙到轻量级的数据结构中。 在烘焙期间,Umbra首先对场景进行体素化 ,然后将体素分组为单元,然后将这些单元与门合并。 除一些其他重要位外,此数据在Unity中也称为遮挡数据 。
In the runtime, Umbra then performs software portal rasterization into a depth buffer, against which object visibility can be tested. In practice, Unity gives Umbra a camera position, and Umbra gives back a list of visible objects. The visibility queries are always conservative, which means that false negatives are never returned. On the other hand, some objects may be deemed visible by Umbra even though in reality they appear not to be. It’s important to realize that, while this system appears similar to what was shipped with previous Unity versions, the entire system has been basically rewritten. A lot has changed for the better, both internally and externally!
然后,在运行时中,Umbra将软件门户栅格化到深度缓冲区中 ,以对对象可见性进行测试。 在实践中,Unity为Umbra提供了一个摄像头位置,Umbra返回了可见对象的列表。 可见性查询始终是保守的 ,这意味着永远不会返回假阴性。 另一方面,某些对象可能被Umbra视为可见,即使实际上它们似乎不是。 重要的是要认识到,尽管该系统看起来与Unity先前版本附带的系统相似,但整个系统基本上已被重写。 内部和外部都发生了很大的变化!
How to Use Umbra There are obviously a few considerations in getting the best out of occlusion culling. Ideally, you’d want the least conservative result as fast as possible. There are, however, tradeoffs involved. The more accurate (i.e. the least conservative) results you want, the higher-resolution data you need to generate. However, higher-resolution data is slower to traverse in the runtime, yielding slower occlusion culling. If occlusion culling requires more frame time than it saves by culling, it obviously doesn’t make a whole lot of sense. On the other hand, very quick culling isn’t of much help if only a few objects are culled. So it’s a balancing act.
如何使用本影最好地考虑一些要消除遮挡剔除的因素。 理想情况下,您希望尽快获得最保守的结果。 但是,要进行权衡。 所需的结果越准确(即最不保守),则需要生成的分辨率越高的数据。 但是,高分辨率数据在运行时的遍历速度较慢,从而导致遮挡剔除速度较慢。 如果遮挡剔除所需的帧时间多于剔除所节省的帧时间,则显然没有任何意义。 另一方面,如果仅剔除少量对象,则非常快的剔除没有太大帮助。 因此,这是一种平衡行为。
Smallest Hole The input is controlled using the smallest hole parameter. When voxelizing the occluder geometry, smallest hole maps almost directly to the voxel size. This means that if your geometry contains intentional holes, gaps or cracks that you wish to see through, using a smallest hole smaller than these is a good idea. On the other hand, a lot of the time the geometry contains lots of unintentional cracks that you do not wish to see through. A reasonable voxel resolution will patch these up. It may help to think about smallest hole as the “input resolution” of the bake.
最小的Kong的输入受到控制,最小的Kong参数。 体素化封堵器几何形状时,最小的Kong几乎直接映射到体素大小。 这意味着,如果您的几何图形包含您希望看到的故意的Kong,间隙或裂缝,则使用比这些小的最小Kong是个好主意。 另一方面,很多时候几何图形包含许多您不希望看到的意外裂纹。 合理的体素分辨率将修补这些问题。 将最小的Kong视为烘烤的“输入分辨率”可能会有所帮助。
Note that setting smallest hole into a ridiculously small value means that baking will be unacceptably slow and/or take up a monumental amount of memory in the editor. In some rare cases, it may even cause the bake to fail due to insufficient memory. Then again, while using a larger value will be faster and more memory-friendly, it may cause Umbra to not see through things like grates or fences. So bigger isn’t always better either. In general, a smallest hole as large as possible without visible errors is desirable. In practice, we’ve found that values between 5 cm to 50 cm work fairly well for most games where the scale is “human-like”. The default value in Unity is 25 cm, and it’s a good starting point.
请注意,将最小的Kong设置为一个可笑的较小值意味着烘烤将变得不可接受地缓慢和/或占用编辑器中的巨大内存。 在极少数情况下,由于内存不足,它甚至可能导致烘烤失败。 再说一次,虽然使用较大的值将更快且对内存更友好,但这可能会导致Umbra看不到格栅或栅栏之类的东西。 因此,更大并不总是更好。 通常,需要尽可能大的,没有可见误差的最小Kong。 在实践中,我们发现在5厘米到50厘米之间的值对于大多数比例类似于“人类”的游戏来说效果很好。 Unity中的默认值为25厘米,这是一个很好的起点。
So as the name implies, a small value means that very fine features are captured in the occlusion data. Under the hood, this directly maps to how large cells Umbra creates. Lots of small cells mean lots of small portals between them, and naturally it’s more expensive to rasterize a large amount of small portals than vice versa. The effects of changing smallest occluder can be seen in the picture below. Note how the depth buffer, which is essentially what Umbra sees, loses detail as smallest occluder increases.
顾名思义,较小的值表示在遮挡数据中捕获了非常好的特征。 在引擎盖下,这直接映射到Umbra创建的大单元格。 许多小型单元格意味着它们之间有许多小型门户,并且自然而然地,光栅化大量小型门户比反之更为昂贵。 下图显示了更换最小阻塞器的效果。 请注意,深度缓冲区(实际上就是Umbra看到的)如何随着最小遮挡物的增加而丢失细节。
Backface threshold Perhaps the most difficult parameter to grasp is called backface threshold. While in many cases you don’t really need to change it, there are some situations in which it may come in handy to understand how it affects the generated data.
背面阈值也许最难掌握的参数称为背面阈值 。 尽管在很多情况下您并不需要真正更改它,但是在某些情况下,可能需要使用它来了解它如何影响生成的数据。
First, it’s important to note that the parameter exists only for a single purpose: occlusion data size optimization. This means that if your occlusion data size is OK, you should probably just disregard backface threshold altogether. Second, the value is interpreted as a percentage, so a value of 90 means 90% and so on.
首先,请务必注意,该参数仅出于单一目的而存在: 遮挡数据大小优化 。 这意味着,如果您的遮挡数据大小合适,则可能应该完全忽略背面阈值。 其次,该值被解释为百分比,因此值90表示90%,依此类推。
OK so what does backface threshold actually do then? Well, imagine a typical scene that consists mostly of solid objects. Furthermore, there may be a terrain mesh whose normal points upwards. Given such a scene, where do you want your camera to be? Well, certainly not underneath the terrain, that’s for sure. Also, you probably don’t want your camera to be inside solid objects either. (Your collision detection normally takes care of that.) These invalid locations are also ones from which you tend to “see” mostly back-facing triangles (although they may of course get backface-culled). So in many cases it’s safe to assume that any location in the scene, from which the camera sees a lot of back-facing triangles, is an “invalid” one, meaning that the in-game camera will never end up in those locations.
好吧,那么背面阈值实际上是做什么的? 好吧,想象一个典型的场景,它主要由固体物体组成。 此外,可能存在一个地形网格物体,其法线指向上方。 在这样的场景下,您要将相机放在哪里? 好吧,那肯定不在地形之下。 另外,您也可能不希望相机位于实体内部。 (通常由碰撞检测来解决。)这些无效位置也是您倾向于从中“看到”大部分背面三角形的地方(尽管它们当然可能会被背面剔除)。 因此,在许多情况下,可以安全地假设场景中相机看到许多背面三角形的任何位置都是“无效”的,这意味着游戏中的相机永远不会在这些位置结束。
The backface threshold parameter helps you take advantage of this fact. By defining a limit of how much back-facing geometry can be seen from any valid camera location, Umbra is able to strip away all locations from the data that exceed this threshold. How this works in practice is that Umbra will simply do random-sampling in all cells (see the previous post) by shooting out rays, then see how many of those rays hit back-facing triangles. If the threshold is exceeded, the cell can be dropped from the data. It’s important to note that only occluders contribute to the backface test, and the facing of occludees doesn’t bear any relevance to it. A value of 100 disables the backface test altogether.
背面阈值参数可帮助您利用这一事实。 通过定义从任何有效摄像机位置可以看到多少背面几何形状的限制,Umbra能够从超过此阈值的数据中删除所有位置。 实际上,这是如何实现的,Umbra会通过发出光线来简单地在所有单元中进行随机采样(请参阅上一篇文章),然后查看其中有多少光线击中了背面三角形。 如果超过阈值,则可以从数据中删除该单元格。 重要的是要注意,只有遮挡物才有助于背面测试 ,而遮挡物的面与它无关。 值为100将完全禁用背面测试。
So, if you define the backface threshold as 70, for instance, to Umbra this means that all locations in the scene, from which over 70% of the visible occluder geometry doesn’t face the camera, can be stripped away from the occlusion data, because the camera will never end up there in reality. There’s naturally no need to be able to perform occlusion culling correctly from underneath the terrain, for instance, as the camera won’t be there anyway. In some cases, this may yield pretty significant savings in data size.
因此,如果您将背面阈值定义为70(例如,Umbra),则意味着可以从遮挡数据中删除场景中的所有位置(可见遮挡物的70%以上都不面向相机)。 ,因为相机永远不会在现实中终结。 自然地,无需从地形下面正确执行遮挡剔除,例如,因为照相机根本不会在那里。 在某些情况下,这可能会节省大量数据。
It’s important to stress that stripping away these locations from the occlusion data means that occlusion culling is undefined in these locations. “Undefined”, in this context, means that the results may be correct, incorrect (pretty much random) or return an error. In the case of an error, all objects are simply frustum culled.
需要强调的是,从遮挡数据中删除这些位置意味着在这些位置未定义遮挡剔除。 在这种情况下,“未定义”表示结果可能是正确的,不正确的(几乎是随机的)或返回错误。 在发生错误的情况下,所有对象都将被平截锥体剔除。
Of course in some cases, there just happens to be some amount of back-facing geometry in valid camera locations too. There may be a one-sided mesh that has been, possibly erroneously, tagged as an occluder. If it’s a large one, it may cause the backface test trigger in nearby areas, resulting in culling artifacts (=errors). This is why the default value of backface threshold in Unity is 100, meaning the feature is disabled by default.
当然,在某些情况下,在有效的摄像头位置也恰好有一些背面几何形状。 可能有一个单侧网格已被错误地标记为封堵器。 如果太大,则可能会在附近区域触发背面测试触发,从而导致剔除伪影(=错误)。 这就是为什么Unity中背面阈值的默认值为100,这意味着默认情况下该功能处于禁用状态的原因。
Feel free to experiment with the parameter. Try reducing the value to 90, which should drop a lot of data underneath terrains for example. See how it has any noticeable effect on the occlusion data size. You can go even lower if you want. Just remember to do so at your own risk. If you start popping into rendering artifacts, increase the value back to 100 and see if it fixes the problems.
随时尝试使用该参数。 尝试将值减小为90,例如,这会在地形下丢弃大量数据。 了解它如何对遮挡数据大小产生显着影响。 如果需要,您可以更低。 请记住,后果自负。 如果您开始弹出渲染工件,则将该值增加回100,看看是否可以解决问题。
To be continued… In the next post, I’ll go into some best practices and recommendations for how to get optimal results out of occlusion culling. Please visit www.umbrasoftware.com for more information about Umbra.
待续……在下一篇文章中,我将介绍一些最佳实践和建议,以帮助您从遮挡剔除中获得最佳结果。 请访问www.umbrasoftware.com了解有关Umbra的更多信息。
Part II Part III
第二 部分第三部分
翻译自: https://blogs.unity3d.com/2013/12/02/occlusion-culling-in-unity-4-3-the-basics/