unity3d游戏开发之移动开发优化详解.docx
《unity3d游戏开发之移动开发优化详解.docx》由会员分享,可在线阅读,更多相关《unity3d游戏开发之移动开发优化详解.docx(7页珍藏版)》请在冰豆网上搜索。
unity3d游戏开发之移动开发优化详解
优化正如PC一样,iOS和安卓(Android)等移动平台也存在各种性能级别的设备。
您可以轻松找到一部渲染效果比其他手机好10倍的手机。
缩放方法非常简单:
∙确保它在基准配置上正常运行
∙在高性能配置上使用更多特效:
∙分辨率
∙后处理
∙多重采样抗锯齿
∙各向异性
∙着色器
∙特效/粒子密度,打开/关闭
注重GPU
图形性能与填充率、分辨率和几何体复杂度(顶点数)息息相关。
如果找到方法剔除更多渲染,那么这三个要素的值都会降低。
此时,遮挡剔除可起到有效作用。
Unity会自动剔除视锥外的对象。
在移动平台上,基本上会受到填充率的约束(填充率=屏幕像素*着色器复杂度*透支度),着色器过于复杂是导致问题出现的最常见原因。
因此,请使用Unity自带的移动着色器或自己设计,但要尽可能简单。
如果可行,请将代码移动到顶点着色器中,简化像素着色器。
如果降低质量设置(QualitySettings)中的纹理质量(TextureQuality)后游戏运行速度加快,那么很可能是受内存带宽所限。
此时可压缩纹理、使用贴图细化,降低纹理大小等。
LOD(细节等级)使对象更简单,或移向远方后完全消除。
主要目的为减少绘制调用的次数。
--来自狗刨学习网
出色实践
移动GPU对于自身产生多少热量、使用的电量以及尺寸大小或噪音大小有严格限制。
与台式机部件相比,移动GPU的带宽较小、运算器(ALU)性能和纹理功率也较低。
GPU的架构也进行了调整,以尽量使用最小带宽和功率。
Unity针对OpenGLES2.0进行了优化,使用GLSLES(类似于高级着色语言HLSL)着色语言。
内置着色器大多使用高级着色器语言(即HLSL,也称之为Cg)编写。
针对移动平台,其被交叉编译成GLSLES。
如果您想要,也可以直接编写GLSL,但这样会限制您访问OpenGL平台(如移动+Mac),因为目前还没有GLSL->HLSL转换工具。
在HLSL中使用浮点/半浮点/固定(float/half/fixed)类型时,它们在GLSLES中会以highp/mediump/lowp精度限定符结尾。
以下列出了一些出色实践:
∙尽量使材质数目减至最低,便于Unity轻松进行批处理。
∙使用纹理精灵(大贴图包含多个子贴图),而非许多单个纹理。
使加载速度更快,状态转换更少,批处理简单方便。
∙如果使用纹理精灵和共享材质,请用Renderer.sharedMaterial代替Renderer.material。
∙向前渲染像素灯比较耗性能。
∙尽量使用光照贴图代替实时灯光。
∙在质量设置中调整像素灯数目。
基本上只有方向灯为逐像素,其他都为逐顶点。
当然,这取决于游戏本身。
∙在质量设置(QualitySettings)中尝试调整灯光的渲染模式(RenderModeofLights),以获得正确优先级。
∙避免使用抠图(透明度测试)着色器,除非真正有必要。
∙将透明(alpha混合)屏幕的覆盖范围保持在最小。
∙努力避免多个灯光照亮任何给定对象的情况。
∙努力降低着色器通道(阴影、像素灯、反射)的总数目。
∙渲染顺序很关键。
一般情况下:
∙从前往后完全不透明的对象。
∙大致从前往后经alpha测试的对象。
∙天空盒。
∙alpha混合对象(若需要,从后往前)。
∙在移动平台上进行后处理性能消耗大,请谨慎使用。
∙粒子:
减少透支,尽量使用最简单的着色器。
∙每一帧都要修改的网格使用双缓存:
着色器优化
检查填充率绑定是否容易:
如果降低显示分辨率,游戏运行速度是否加快?
若是,即受到了填充率的限制。
尝试使用以下方法降低着色器的复杂度:
∙避免使用alpha测试着色器,而是采用alpha混合版本。
∙使用简单、已优化的着色器代码(如Unity附带的“移动(Mobile)”着色器)。
∙避免在着色器代码中使用性能消耗大的数学函数(如指数表达式、指数、对数、余弦、正弦、正切等)。
考虑使用预计算的查找纹理代替。
∙为实现最佳性能,尽可能选择最低数值的精度格式(Cg中的浮点、半浮点和固定(float,half,fixed))。
注重CPU
游戏受到GPU像素处理限制的情况时有发生。
导致最终出现CPU未充分使用的情况,多核移动CPU尤其如此。
将GPU中的一些工作移出来,放到CPU中处理往往是比较明智的做法(Unity处理所有这些操作):
网格蒙皮、小对象的批处理、粒子几何体更新。
慎用,不要盲目地全放到CPU中处理。
如果不受绘制调用限制,那么随着剔除效率的降低和更多对象受到灯光影响,批处理的实际性能会变差!
出色实践
∙在移动设备上每帧的绘制调用不要超过数百次。
∙FindObjectsOfType(以及Unity的一般getter属性)非常慢,慎用。
∙设置非移动对象的静态(Static)属性,允许静态批处理等内部优化。
∙消耗大量CPU周期进行遮挡剔除和更好的排序(利用EarlyZ-cull)。
物理(Physics)
物理(Physics)占用CPU的比重较大。
可以通过编辑器(Editor)分析器对其进行分析。
如果物理似乎占用了太多CPU时间,请:
∙将Time.fixedDeltaTime(位于工程设置(Projectsettings)->时间(Time))调至可接受的最高值。
如果游戏运行缓慢,需要的固定更新次数很可能比快动作游戏少。
快节奏游戏须更频繁地计算,这样一来,fixedDeltaTime就要降低,否则碰撞可能会失败。
∙Physics.solverIterationCount(物理管理器(PhysicsManager))。
∙尽量少使用布(Cloth)对象。
∙必要时才使用刚体(Rigidbody)。
∙在首选网格碰撞器中使用原始碰撞器。
∙永远不要移动静态碰撞器(如不带刚体的碰撞器),否则可能对性能造成很大影响。
∙在分析器(Profiler)中显示为“StaticCollider.Move”,但真正的处理过程是在Physics.Simulate中进行。
∙如有必要,添加一个刚体(RigidBody)并将isKinematic设为true。
∙在Windows系统中,必要时可以使用NVidia’sAgPerfMon分析工具包获取更多细节信息。
AndroidGPU以下是一些流行的移动平台体系架构。
硬件供应商与PC/控制台空间不同,GPU架构与“常用”GPU相比也有很大差异。
∙ImgTecPowerVRSGX–基于平铺延迟:
在小单元内渲染所有内容(如16×16),只为可见像素着色。
∙NVIDIATegra–经典:
渲染所有内容。
∙QualcommAdreno–平铺:
在单元内渲染所有内容,在大单元内进行设计(如256k)。
Adreno3xx可切换到传统模式。
∙ARMMali平铺:
在单元内渲染所有内容,在小单元内进行设计(如16×16)。
抽出一些时间了解不同渲染方法,并相应设计游戏。
特别注意排序问题。
在开发周期前期定义支持的最低终端设备。
设计游戏时开启分析器对其进行测试。
使用针对特定平台的纹理压缩。
屏幕分辨率安卓(Android)版本
iOS
GPU
只考虑PowerVR架构(基于平铺延迟)。
∙ImgTecPowerVRSGX。
基于平铺延迟:
渲染单元内所有内容,只对可见的像素着色。
∙ImgTec.PowerVRMBX。
基于平铺延迟,固定函数–iPhone4/iPad1之前的设备。
这意味着:
∙贴图细化并非必须。
∙反锯齿和反向异性耗费的性能很少,有些情况下iPad3上并不需要。
缺点:
∙如果每帧的顶点数据(顶点数*顶点着色器之后所需的存储空间)超过驱动器分配的内部缓存,那么场景须“分开”,这会耗费性能。
之后,驱动器可能会分配更大缓存,或者您可能需要减少顶点数目。
非常复杂的着色器上约有10万个顶点时,在iPad2(iOS4.3)上会趋于明显。
∙TBDR须为平铺和延迟部分分配更多晶体管,理论上留给“原始性能(rawperformance)”的晶体管就较少。
在TBDR上获得绘制调用的GPU时间非常难(几乎不可行),使分析更加困难。
屏幕分辨率
iOS版本
动态对象
资源包
∙资源包可以在一定限度内保存缓存到设备上。
∙用编辑器(Editor)API进行创建
∙卸载
∙AssetBundle.Unload
∙有一个选项供卸载资源包,但会隔开已加载的资源。
∙即使是在场景中引用,也会关闭所有已加载资源。
∙Resources.UnloadUnusedAssets
∙卸载场景中不再引用的所有资源。
记住关闭不再需要的资源引用。
∙公共变量和静态变量永远不能回收利用。
∙Resources.UnloadAsset
∙从内存中卸载一个特定资源。
需要时可以从磁盘中重新加载。
iOS上对同时下载资源包的数目有限制吗?
(例如能否同时(或每个帧)安全下载10个资源包)?
通过OS提供的不同步API实施下载,所以OS决定需要创建多少线程以供下载。
多个并行下载时应注意可以支持的设备总带宽和空余内存百分比。
每个并行下载分配自己的临时缓存,应注意这些缓存未占用完内存。
资源
∙资源需要被Unity识别,以放入发布版中。
∙将.bytes文件扩展作为二进制数据添加到想要Unity识别的任何原始字节。
∙将.txt文件扩展作为文本资源添加到想要Unity识别的任何文本文件中。
∙发布时资源会转成平台适用的格式。
∙Resources.Load()
低级错误列表
∙纹理未经过适当压缩
∙不同情况下使用不同的分辨率,除非肯定不要压缩,否则一律压缩纹理
∙ETC/RGBA16–安卓(android)默认设置
∙可根据GPU供应商进行调整
∙可行时使用ETC是最佳方法
∙alpha纹理可以使用两个ETC文件,其中一个通道用于alpha
∙PVRTC–iOS默认设置
∙适用于大多数情况
∙纹理启用了Get/Setpixels–加倍封装,除非需要Get/Set,否则不要勾选
∙运行时从JPEG/PNG中加载的纹理不压缩
∙大mp3文件在加载时标记为解压
∙附加场景加载
∙未使用的资源在内存中保留为未清理
∙静态区域
∙非卸载的资源包
∙如果偶然崩溃,尝试软件开发工具包或带2GB内存的设备(如Ipad3)。
有时控制台中未出现任何问题,仅为偶然性崩溃。
∙快速脚本调用和剥离可能导致在iOS上偶然崩溃。
试试没有这两项会如何。