在Unity开发Android应用优化指南(上)一文中,从游戏性能,脚本等方面进行了分析和总结,今天这篇文章将由Niels Tiercelin继续分享在光照,UI,着色器等方面优化的经验。(一切从尽量优化的角度出发)
光照
接下来讨论渲染优化,首先要讲的是光照。尽可能不要使用动态光照,尽量使用不带光照的纹理。因为光照计算需要占用大量资源,尤其是当场景中有很多物体需要渲染时。
(1)烘焙光照
如果可以,尽量利用烘焙光照(Baked Lighting)技术来满足项目需求,该技术会将光照结果一次性地直接“绘制”在纹理中,最后游戏中无需进行任何计算。通过这种方法您可以随意放置光源,制作复杂场景而无需考虑性能,因为所有光照都会被烘焙到纹理中。当然,这样就失去了动态光照的一些特性,例如动态阴影,且由于光源没有任何变化,物体在场景中的移动可能会让玩家产生违和感。
(2)光照探头
可以利用光照探头(Light Probes)来解决烘焙光照无法动态变化的问题。这些探头会在光照烘焙时将环境光信息存储起来,不同的是它并非保存在纹理而是停在空间的某个位置。通过这种方式,物体在探头活动区域内移动时就会被预先烘焙好的光照“照亮”。
(3)阴影投射器
另一种方式是为场景中的重要角色使用假动态阴影。可以在角色的脚底放个圆形黑色纹理,让玩家觉得“这就是阴影”,和老式电影一样。当然前提是这种做法适合您的游戏。
右侧:初始阴影 —— 左侧:“blob 阴影” 纹理
您也可以使用阴影投射器,这种技术会利用物体本身的网格信息,在其下方投射出以假乱真的阴影。尽管这不是动态光源投射出的那种真实阴影,但用在项目中应该足够了,而且它使用的资源也更少。还可以借助 Fast Shadow Receiver插件来实现阴影投射。3D空间中,阴影是不可或缺的重要元素。然而阴影的渲染会给GPU带来很大的负担。
(4)阴影
如果一定要用动态光照,请保证数量越少越好,并且整个游戏中仅使用一个方向光源。当然,使用动态光源有个很大的益处,尤其是在3D世界中,可以实现比较真实的阴影,但这也是光照处理过程中占用资源最多的步骤。为了达到实用与性能之间的平衡,可以通过调整参数来得到理想的阴影效果。
(5)方向光设置
在场景唯一的方向光上,可以将Culling Mask设为仅影响需要被光照的GameObject,以免消耗更多性能。多多尝试设置 Shadows Resolution 的值,找到刚好合乎需求的设置。当然,分辨率越低,消耗的资源就越少。但有一点要注意,编辑器中的效果不一定与设备上的显示效果一致。例如设置了某种低分辨率阴影,在电脑上看起来可能很粗糙,但在设备上可能刚刚好。因此记得在设备上查看最终结果。
(6)质量设置
打开Quality Settings (Edit > Project Settings > Quality),看看其中的设置。
这些设置会切实影响到游戏性能表现,所以尽量理解它们的作用。
Pixel Count:如需减少光照计算所需的量,将 “Pixel Count” 的值降为1,如果没有任何光源则设为0。
Antialiasing:最好不要启用抗锯齿(Antialiasing),因为对于移动设备来说这是消耗过大。
Soft particles:如果对软粒子没有特别需求则不要启用该选项。
Shadows:仔细调整阴影相关的参数,它非常重要。
软阴影(Soft Shadows)会占用更多资源,您可以选择仅使用硬阴影“Hard Shadows Only”。不过硬阴影有个缺点,分辨率很低时这种阴影看起来颗粒感很强。解决方案是设置 “Shadow Projection” 选项,将“Stable Fit” 改为 “Close Fit”,这样可以或多或少地缓解这种颗粒感。如果调整后画面看起来效果很差,别急!在设备上运行看看实际效果。最后,慢慢减少“Shadow Distance”的值。可以看到远处的阴影开始消失。这个选项就是用来设置需要处理的阴影距离。超过该距离的阴影会被忽略。所以将该值减小至理想效果即可。现在Quality Settings窗口如下图:
(7)纹理
如果仔细研究编辑器日志,会发现纹理是游戏内存占用大头。大多数情况下,这些纹理占用的内存远远地超过了它们的价值。可以先在项目窗口中点击纹理,进入纹理的 “Import Settings”。点击 “Advanced” 箭头,勾选 “Generate Mip Maps”。Unity强烈推荐勾选该选项,它可以加快纹理的载入速度,降低渲染时间。
最后,可以使用纹理图集(Atlas)减少DrawCall。所谓图集就是一张大的纹理,其中包含游戏中部分或全部的纹理。这种做法确实可以带来很大的性能提升!
(8)UI
谈到Unity Android优化,另一个很大的课题是UI方面的优化。可以利用一些小技巧来获得最佳性能表现。
Sprites
在UI中使用精灵(Sprite)时,保证其中透明区域越少越好,因为这会影响性能表现。可以像纹理一样将所有UI Sprite放到一个图集中,然后将 “Max Size” 设为可以接受的值。同时勾选 “Generate Mip Maps” 选项,UI不仅需要更快的渲染速度,同时最好也能流畅地显示在屏幕上。
(9)Canvas
Unity中,UI是与Canvas一起搭配使用的。尽量减少Canvas存在的数量,因为一个Canvas就表示需要进行一次渲染处理。有时候您的UI不需要与用户交互,此时可以移除 “Graphic Raycaster” 组件。因为后者是用来检测交互操作的。此外,取消勾选“Pixel Perfect”选项可以获得更佳性能,尤其是使用Scrool Rects时。
(10)文本与图像
文本(Text)组件对移动设备的性能要求很高,所以可以禁用 “Rich Text”功能。如果图像与文本组件无需与玩家交互,可以取消勾选 “Raycast Target”,从而避免不必要的射线检测计算。
(11)字体
使用文本对象时常希望自己设置字体。但要小心,网上的一些低质量字体可能会带来性能方面的问题。尽量使用字符集较小的字体,如果遇到性能问题,请尝试取消勾选所有Text组件的 “Best Fit”选项。
(12)UI材质
经确认,如果图像和文本组件的材质一栏为空,那么它将拖慢运行速度。我们要做的是新建一个材质,着色器就用“UI/Default”,然后让所有的图像和文字组件使用该材质。
(13)Rect Mask 2D
Rect Mask 2D是一种UI组件,与Mask组件类似。不同的是前者可以在UI元素超出遮罩区域时禁用这个元素,从而避免多余的渲染工作。
(14)Scroll Rect
另一种UI组件Scroll Rect是用来显示大量内容的,它会隐藏部分内容并允许用户进行滚动操作。这种组件的交互可以给玩家带来更佳体验,但尽量少用,因为它对移动设别并不是特别友好。可以将其与Rect Mask 2D组件配合使用,以获得更佳性能。
(15)Canvas Group与动画菜单
与菜单元素交互时,一般做法是在元素显示时启用,不显示时禁用。但这并不是最高效的办法。实际上,启用与禁用会重新激活部分GameObject上的一些操作。例如前面提到的Scroll Rect,在启用时会重新载入其中填充的内容,这种操作可能会产生卡顿。还有一种方法是就让GameObject保持激活,但使用Canvas Group进行管理。
这些组件很实用,它可以将UI元素分组,并整体地控制它们的行为。您可以尝试调整透明度,即Canvas Group的“Alpha”,然后禁用UI的交互功能(使用“Interactable” 和 “Blocks Raycasts”选项)。
(16)着色器
最后也是最重要的,来探讨一下着色器。从渲染的角度来看,这是一种很神奇的东西,但对于移动设备,它可能会瞬间榨干设备的性能,因此一定要当心。从Niels的经验来看,着色器的Keyword越少越好、着色器数量越少越好、内容越简单越好。PostProcessing着色器是性能消耗大户,所以不要在移动设备上使用,或者提前做好功课做足测试,保证移动设备上的运行性能。
注:转自unity官方中文论坛