技术分享连载(十四)

技术分享连载(十四)

【技术分享】是UWA推出的技术交流栏目,我们会定期将开发团队中反馈的常见问题加以总结并梳理在此,以供大家参考。

这是侑虎科技第45篇原创文章,欢迎转发分享,未经作者授权请勿转载。同时如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)


UI输入

Q1:能否对提升NGUI的渲染效率提供一些思路?

开发团队可以从以下几点入手:
1、通常一个Panel会产生1个或多个Draw Call,以一个Panel为单位,Draw Call 的数量通常由当前 Panel 中使用的Atlas、Font的数量所决定。

2、要降低UI渲染时的 Draw Call数量则需要对 Atlas 的制作进行合理的规划,即在保证使用较少的 Atlas 的同时,还需要保证 Atlas之间不会存在交叉遮挡。

3、要注意UI Texture的使用,每个UITexture自身会占用一个Draw Call,同时如果其Depth值穿插在了其他来自相同Atlas的UISprite中,还会导致Draw Call的打断,造成不必要的额外Draw Call。

4、另外还可以借助Panel Tool和Draw Call Tool来对UI部分的Draw Call进行分析,前者可以显示每个UIPanel包含了多少个Draw Call,而后者可以显示每个Draw Call由哪些UIWidget组成。


图形渲染

Q2:如下图所示,第一张显示的是没有烘培Lightmap的场景效果,里面有一盏点光源;第二张显示的是烘培Lightmap后的场景效果。请问为什么同一盏点光源照亮的效果差别那么大?

UWA Tech Doc
UWA Tech Doc

简单来说,这就是实时的直接光照和全局光照的差别。
在渲染时前者只能处理光源和单个物件之间的直接光照,而后者在烘焙时是通过光线跟踪或者辐射度等复杂算法,计算出所有物体各个表面之间相互反射的光照信息,这也是烘焙Lightmap需要较久的时间的原因 。可以发现在全局光照下,即使是物体的背面也会因为其它表面的反射而被照亮,这在直接光线下就无法实现这样的效果。


骨骼动画

Q3:在UWA给出的报告中,我们发现了Animator过高的情况,其中UI和角色各占一半。我们之前一直选择CullUpdateTransforms,通过阅读Unity官方文档发现CullCompletely更符合我们的现状,想请教下如果我们选择CullCompletely可能会有什么隐患呢?

使用 CullCompletely 在开启 RootMotion 时是需要注意的,比如人物有一个巡逻动画是通过 RootMotion 制作的,那么在人物走出屏幕后,其动画就停止了,即不会再走回屏幕中。


资源管理

Q4:我有一个UI预设,它使用了一个图集, 我在打包的时候把图集和UI一起打成了AssetBundle。我在加载生成了GameObject后立刻卸载了AssetBundle对象, 但是当我后面再销毁GameObject的时候发现图集依然存在,这是什么情况呢?

这是很可能出现的。unload(false)卸载AssetBundle并不会销毁其加载的资源 ,是必须调用 Resources.UnloadUnusedAssets才行。关于AssetBundle加载的详细解释可以参考我们之前的文章:你应该知道的AssetBundle管理机制。


内存管理

Q5:我们现在有一个场景,Draw Call和面数都在正常范围内,Camera的距离也和其他场景一样,但是VBO却非常高。下图是该场景的数据情况,该场景下有很多复用的模型,如果不勾选Static那VBO会下降,但是Draw Call会上升。那我能否通过合并模型的方式把VBO降下来呢?

UWA Tech Doc

当你勾选Static时,Unity 会将其进行 Static Batching,进而将生成一个较大的VBO来进行渲染,同时降低Draw Call。而如果不勾选时,则引擎无法对其进行Batch,所以VBO会降低,而Draw Call升高。

对此,我们的建议如下:
1、一般来讲,降低Draw Call的意义大于降低VBO;
2、在Draw Call较低的情况下,比如当前的50+,可以考虑适当增加一些Draw Call来降低VBO的占用,一方面可以降低带宽的压力,另一方面也可以适当降低一些内存。