作为数字3D内容的创造者,我们总希望自己的作品能呈现出它们最好的一面。在某些情况下,我们对目标硬件具有完全的控制,因此我们可能会试图将渲染能力推向极限。在情况下,我们可能会尝试创建一个在各种硬件上都能运行的体验效果。

动机
无论哪种情况,我们都可以通过选择一些性能优化方式,改善CPU和GPU的运行时间。例如:遮挡剔除(Occlusion Cullings)、纹理图集(Texture atlasing)、静态和动态批处理、GPU实例化(GPU instancing)、着色器回退(Shader fallbacks)、多线程、光照贴图、优化垃圾回收、脚本等。在3D图形方面,对网格使用多个不同的LOD(Levels of detail)是一种已经过验证且可靠的技术。

112732rvbvcnujbi2tyybn.png
LOD0是传统的原始网格,每一个增加的LOD是对上一层LOD的多边形数量进行抽取或减少后所得

如果LOD技术已经被验证是可靠的,那么为什么还要讨论它呢?因为可用的LOD还不够完美。

以下任何一个原因,都可能使无法充分利用LOD的优势。
需要艺术家来处理LOD。例如:单独处理,通过UI来对它们进行批量处理等。 需要建立一个自定义管线。 涉及一些软件工程方面的工作。 涉及对工作流程的不同阶段中使用的各种产品进行评估,但是各种生产方式之间可能各不相同。 最终可能需要权衡使用LOD的利弊。


综合上述原因,我们在Unity Labs中尝试了一个实验性项目AutoLOD,用来挑战针对LOD使用的障碍。

你可以访问Github来获取试验中所使用的代码:
https://github.com/Unity-Technologies/AutoLOD

112738vl9yr9war1wrwvzb.png

如果生成的LOD不正确,还可以针对每个模型文件进行重写。

112738fooc020zrzrrrzr7.png

我们可以为某个文件单独更改Simplifier/Batcher下拉框的设置,或者直接关闭导入时自动生成,并手动提供LOD。甚至可以在LOD链中添加额外的LOD。这个LOD链会被包含到项目中导入版本的模型文件之中,因此无需使用额外的预制件来设置LODGroup。

SceneLOD
SceneLOD的灵感来自于Erikson, C., D. Manocha和 W. Baxter发表的论文2001 I3D Paper。我们决定创建一个与Unity中现有的LODGroup组件一起工作的实现,这样就不需要一个定制版本的Unity了。LODGroup组件的体积包围盒层级(目前是一个八叉树),控制着使用哪个LOD被用于渲染场景。

2001 I3D Paper:
https://www.cs.unc.edu/Research/ProjectSummaries/hlods.pdf

为什么是HLOD?
HLOD(Hierarchical Level of Detail)作为一种性能优化,将场景中的独立网格进行分区,以便能使用一个组合的网格进行代替。

传统的LOD会根据屏幕大小、距离、视角或指标来选择一个合适的网格表示物。无论选择哪个LOD,每个渲染的网格都需要增加一次额外的绘制调用。传统LOD的局限性是绘制调用次数在总量上没优化,因为每个对象的LOD链是单独评估的。静态批处理只解决了部分问题,因为它只根据共享材质进行合批。绘制调用通常会加重CPU的负担,所以减少绘制调用次数能提高CPU的性能。

HLOD通过将特定空间内的所有对象组合成一个单一网格,并利用纹理图集来实现单一材质,可以减少绘制调用的数量。对于希望在整个场景中显示全景视图的游戏,HLOD能极大的提高性能。在其他情况下,当被作为一组组合网格时,HLOD可能会胜过单个LOD的质量。HLOD的缺点是,在BVH每个节点上的每个HLOD网格都需要额外的内存开销。

性能分析
我们对Asset Store商店中POLYGON-CITY资源包中提供的一个演示场景略作修改。在5秒内,使用Timeline将一个摄像机从一个近距离视图放大到整个城市的视图。测试是在笔记本上进行的。

让我们看看传统LOD和HLOD的分析器视图。

112738vqa5aphdz5ia0q0d.png

随着摄像机镜头的放大和更多场景的显示,上图传统的LOD显示了CPU和渲染开销的增长。

112739qtssy591sqsyttqy.png

对于HLOD,在回放刚开始时传统的LOD是激活的,这就解释了刚开始时的渲染开销。最终一旦HLOD被充分利用后,性能就会接近恒定的CPU和GPU消耗。BVH评估即决定哪些HLOD需要渲染也需要一些CPU消耗。

下面实验是在整个场景呈现在游戏视图中(摄像机固定)和统计窗口打开的情况下进行的。

112739n9qd8sddtmzqymd1.png
静态批处理需要将场景中所有对象标记为静态,然后点击播放,实例化需要在所有使用的材质中启用GPU实例化


112739jdcc1d0k44yqnq3d.png

正如我们看到的,针对一个大型城市场景,HLOD比传统的LOD在性能上提高了1425%,并且将绘制调用数量从1487次减少到仅仅只有6次!

然而,当构建的场景是传统LOD通常无法处理的时候,HLOD才会真正发挥巨大作用。

112740zwgaga41z9pkwv71.png

这个示例场景中包含了原始场景的4个副本,总共有620万个三角形和11655个批处理。渲染速率为83.3ms/43.9ms(CPU/GPU),低于交互响应率。

现在将它与相同场景的HLOD版本进行比较。

112740pg8gf3himkz6khim.png

尽管三角形的个数增加到700万,但仍然以1ms/0.4ms(CPU/GPU)的速率进行渲染,并且只有6个批处理。请记住:尽管副本来源于原始场景,即使城市的每个部分都是独一无二的,你也可以期待有同样的性能表现。

存储成本
在一次构建中,SceneLOD将增加静态网格和纹理的大小,但如果BVH深度也同时减少,这可以相应减少。

HLOD:纹理 36.3 mb 5.3% 网格 599.9 mb 87.6%
LOD:纹理 20.3 mb 20.9%网格 30.0 mb 30.8%

磁盘上未压缩的HLOD网格的大小是1.1GB。

时间成本

一次性
HLOD实现在BVH生成和每个从LOD生成分离出的HLOD生成都有一次性的成本。在场景中添加、移动或删除对象时,这些一次性计算成本将会随时产生。但是SceneLOD会跟踪这些变化,并在后台自动的更新BVH和HLOD。

动态
每当一个摄像机渲染时,遍历BVH并决定在渲染前启用哪些LODGroup组件是非常必要的。

结语
我们发现自动化LOD能够解决一部分在数字化内容创作中存在的痛点。合理的默认值能满足项目的大部分需求,而如果发现有任何网格存在问题,可以根据具体情况对它们进行单独修改。SceneLOD提供了一个HLOD的示例实现,可以用于当前Unity版本的大场景中。如果你愿意用存储成本来换取性能,对一个拥有很多静态元素的特大场景来说,你有可能可以将其渲染性能提高一个数量级。

我们希望这个实验项目能使开发者对自己项目中遇到的性能问题有一些深入的见解,并且让你有能力去构建更为复杂的场景。未来的工作方向还有很多,比如支持动态对象、更好地压缩磁盘上的HLOD、默认的LOD生成器、用于HLOD渲染的不同的着色器配置以及性能优化!
性能, 优化 本主题由 admin 于 2018-6-1 01:47 解除置顶锐亚教育

锐亚教育 锐亚科技 unity unity教程