unity 最后一次unity3d drawcalll 如何避免

腾讯大咖说:腾讯是如何做Unity手游性能优化的
日期: 14:06:34
来源:ITeye
腾讯大咖说:腾讯是如何做Unity手游性能优化的
本文由腾讯WeTest授权发布
作者:chunhe,腾讯资深后台开发工程师。
著作权归作者所有。商业转载请联系WeTest获得授权,非商业转载请注明出处。
俗话说,用户体验不谈性能就是耍流氓。 在PC游戏上的性能问题并没有那么明显,加个内存换个CPU或者刷个主频就能轻松搞定;到了手游时代后情况则显得比较严峻,捉襟见肘的内存使得资源加载时如履薄冰,加上高中低不同配置的机型让性能问题显得更加突出,一个低端机型上的卡顿就可能造成一大批屌丝用户的流失,这当然无法被忽视。
在手游的浪潮之巅,腾讯对于手游品质的要求从1.0到2.0再到现在的3.0,不仅是玩法和内容,在游戏质量的审核上也始终如一的保持着高要求高标准。腾讯游戏的品质管理中心在Unity手游性能上进行了更深层次的挖掘,这是一个腾讯内部非常受欢迎的性能分析产品,无论你是否正在从事Unity相关的工作,听完这个良心产品的故事保证会让你增加90%的魅力值。但在此之前、先要看看你的“性”能到底行不行?
(下文有大量专业术语,有可能引起您的不适,请在家长指导下阅读。)
一.常见的Unity手游性能问题有哪些?
Unity手游的性能问题一直是被业内视为诟病,腾讯公司内部的TDR评审就是一个专门针对技术细节进行专家团评估的环节;早期的TDR评审关注的是内存是否超标、CPU是否饱和、网络流量是否过大等数据,经过近几年手游浪潮的洗礼,现在评审过程中会更加注重细分问题的研究和排查。
如果说左边是玩家经常会遭遇到的表面现象,那右边则是基于Unity引擎深挖后的问题本质。 它们对游戏的具体影响是什么呢?就拿最近比较火的《王者荣耀》来举例,我们有幸参与了它上线前后的几个优化版本的分析,先后遇到过的问题和优化方法主要有下面几个:
由于实时对战游戏的数据包数量巨大,早期版本的帧同步策略会导致比较明显的卡顿,通过进行数据包的合并与优化逐渐解决了卡顿问题;
频繁创建和销毁的小兵对象让CPU爆表了,大量的小兵如果采用实时内存的分配和回收,会产生大量的内存碎片和系统开销,解决方法之一就是采用高效的对象池进行优化,对每个内存对象的状态进行操作即可;
性能分析过程中,发现单人同屏和多人同屏时的开销都很大,通过视野裁剪技术,使得玩家视野外的不必要的特效和渲染可以全部关闭,极大降低了CPU、GPU和内存的开销;
在高中低三档机型上玩游戏时,分别加载不同层次的特效包,这也有助于降低CPU和内存的开销;
性能分析过程中发现副本内wwise音频组件占了30%的CPU时间,果断抛弃之,采用Unity自带音频功能,优化很明显;
游戏内界面采用了UGUI的方式实现,但大量的实时UI变化使得副本内每帧会有230以上的drawcall,导致中低端机型感受到明显卡顿,最终采用UGUI+自研究UI的组合拳,重写了一套紧密结合游戏自身特性的UI来实现战斗血条和浮动文字的效果。
二.手游发布之前的性能分析
近年来,经过若干惨痛的教训之后,业内已经逐渐意识到手游性能已成为了生死存亡的关键,特别是对于做大DAU的手游来说尤为重要。腾讯对于手游性能的测试和监控也是多管齐下,在新版本发布之前会再三确认性能是否符合发布标准,拿王者荣耀这款实时竞技游戏来说,在测试阶段会采集大量的性能数据进行分析,测试经理对各项性能指标进行评估并给出最终质量结论。
如上图所示,首先,功能测试也就是通常所说的人肉测试,用于测试游戏的新、老功能点,测试工程师在工作过程中可以使用进行数据采集;自动化测试则是基于腾讯WeTestgautomator自动化框架来实现,功能类似于Robotium,在无须人力参与的情况下能覆盖到绝大部分技能、角色和关卡;灰度发布指的是在一个很小范围定点推送手游的新版本,并观察运营期的质量情况和玩家反馈。无论是哪种测试方法,在过程中都可以用进行数据采集,在测试完成后,服务器会自动进行数据分析并给出多项性能数据结论;这些性能数据的结论来自于Unity官方的推荐标准值和腾讯游戏海量的经验库,如果同意机器给出的结论则可以巩固当前算法,当然也可以挑战自动分析的结论,帮助后台改进算法,最终版本质量结论还是来自于测试经理的判断。
看到这里是不是有一个疑问:不做性能分析行不行?当然行,并且你的产品照样能发布、能上线,带来的结果就是用户抱怨用户投诉用户流失。生病了、还得老老实实的去看病去吃药;冰冻三尺非一日之寒,一场大病的费用远比日常保养要贵的多,对应测试行业的名言就是“bug发现的越早、修复成本越小”。
三.工具的简介
目前市面上大多数性能工具都还停留在操作系统级别的数据上, 在游戏自身的分析上似乎还缺少点什么,所以腾讯的工程师们觉得还可以往灵魂深处挖一挖,于是就研发了这个手游性能分析工具,可以让用户以最小的成本在真机上进行游戏性能深度分析。常见的游戏质量改进的过程如下图,能帮你完成的是前两个环节,至于第三步、解决问题当然还是要开发人员去改代码了。
通过的深度分析,能够帮助开发者发现当前游戏内分类资源的占用情况。
如上图所示,在资源分析纬度上可以给出如下结论:
资源使用总量是否在合理范围之内。
一个场景内的资源重复率。
资源对象拷贝的数量是否合理。
场景切换时保留的资源详情。
网格、纹理、音频、动画、GameObject等资源是否超标。
在性能分析纬度上,以腾讯的TDR标准为例,在高中低三档机型上会有不同的标准,在三档机型中做了自动的筛选和判定,便于开发人员能更加直观的发现问题。(如下图)
首先、在游戏场景内对于FPS、CPU、PSS的变化趋势是需要重点关注的;其次、对于mono这种只增不减的东西,当然也是关注的重点,mono堆内存的不断分配会直接导致PSS内存增长且不可逆;再次、对于和渲染有关的drawcall,也是手游需要关注的性能指标之一,drawcall太高会导致FPS陡降,造成视觉上的卡顿。
四.同类工具对比
MAT (Memory Analyzer Tool)的缺点:
需要导入HPROF文件再分析;
只能查看java层的内存情况,看不到native堆的详情;
xcodeinstrument 的缺点:
只能用于mac,ios;
只能查看C++ 或 object C 的情况,看不到mono堆的详情;
Unity Profiler 的缺点:
需要单独编译develop版本;
在PC上执行,没法捕获真机数据;
内存数据跟实际真机的数据差异很大、多的时候有几十M差距;
只能看到最近一段时间的数据,看不到总体的详情;
对于Unity大神和开发人员,你更关心的应该是详细的性能数据,都能满足你们。大神会说“我更喜欢看着Unity profiler直接调试啊”,那你还得腾出时间编译一个develop版本、还得重新跑一遍游戏、数据和真机还相差很多,关键是大神哪来那么多时间呢?
所以答案是肯定的,日常测试工作中加入了数据采集和数据分析功能,就可以提高很大的工作效率。
我们常见的产品质量改进流程无非是下面这四步:
测试人员发现问题;
提bug 给开发人员;
开发人员编译develop版本;
开发人员用Unity profiler 定位原因;
用进行游戏测试能帮你省掉后面2个步骤,何乐而不为呢?
通常情况下,开发人员是间隔几个星期甚至几个月才会去做一次性能调优的工作,中间已经隔了N个版本,有很多问题会被埋的很深;基于“问题发现的越早修复成本越小”的硬道理,功能测试人员完全可以用进行日常的版本功能测试,让在后台默默的为你发现各种性能问题。
即插即用、无须编译无须嵌入SDK、真机运行数据;
提供mono内存分配信息和mono快照对比;
能看到整个测试流程中的所有数据,而不仅仅是某一段时间;
被误操作产生的对象拷贝数量;
函数开销排名;
关卡间保留的冗余资源;
五.性能优化的N种武器
作为一个以性能优化为己任的工具类产品,不仅致力于问题的发现和定位,也希望为开发人员提供更多更实用的性能优化方法。
控制贴图大小,尽量不要超过 ;
尽量使用2的n次幂大小的贴图,否则GfxDriver里会有2份贴图;
尽量使用压缩格式减小贴图大小;
若干种贴图合并技术;
去除多余的alpha通道;
不同设备使用不同的纹理贴图,分层显示;
尽量控制模型的面数,小于1500会比较合适;
不同设备使用不同的模型面数;
尽量保持在30根骨骼内;
一个网格不要超过3个material;
N种动画压缩方法;
尽量减少骨骼数量;
采用压缩MP3 和 wav;
资源方面的优化:
使用 Resource.Load 方法在需要的时候再读取资源;
各种资源在使用完成后,尽快用Resource.UnloadAsset和UnloadUnusedAsset卸载掉;
灵活运用AssetBundle的Load和Unload方法动态加载资源,避免主要场景内的初始化内存占用过高;(实现起来真的很难…)
采用www加载了AssetBundle后,要用www.Dispose 及时释放;
在关卡内谨慎使用DontDestroyOnLoad,被标注的资源会常驻内存;
代码的优化:
尽量避免代码中的任何字符串连接,因为这会给GC带来太多垃圾;
用简单的“for”循环代替“foreach”循环;
为所有游戏内的动态物体使用内存对象池,可以减少系统开销和内存碎片,复用对象实例,构建自己的内存管理模式,减少Instantiate和Destory;
尽量不使用LINQ命令,因为它们一般会分配中间缓器,而这很容易生成垃圾内存;
将引用本地缓存到元件中会减少每次在一个游戏对象中使用 “GetComponent” 获取一个元件引用的需求;
减少角色控制器移动命令的调用。移动角色控制器会同步发生,每次调用都会耗损较大的性能;
最小化碰撞检测请求(例如ray casts和sphere checks),尽量从每次检查中获得更多信息;
AI逻辑通常会生成大量物理查询,建议让AI更新循环设置低于图像更新循环,以减少CPU负荷;
要尽量减少Unity回调函数,哪怕是空函数也不要留着;(例如空的Update、FixedUpdate函数)
尽量少使用FindObjectsOfType函数,这个函数非常慢,尽量少用且一定不要在Update里调用;
千万一定要控制mono堆内存的大小;
性能优化就像海绵中的水,又或是内衣里的肉,挤一挤总会有的。同时,性能优化并不是一劳永逸的工作,而是一个漫长而具有挑战的任务;项目的各个阶段都会有性能上的问题,在用户体验的基础上持续进行打磨,持续保持产品的良好性能才能赢得好口碑。(和保持身体健康是一个道理)
Unity手游的性能优化过程更像是一门时空转换的艺术, 持续在CPU和内存之间取得一个平衡。空间不足时则需要释放一些无用数据,以获得更优的空间使用率;时间太长时就需要降低不必要的函数开销。例如在低端机上,为了节约有限的内存空间,静态加载的资源会相对较少,很大一部分资源通过动态加载和释放;而在高端机上则不用考虑空间的限制,可以一次性静态加载更多的资源,省去了不少loading和GC的工作,让游戏体验更加流畅。 Unity目前已经可以使用。
体验地址:
关于测试报告的问题:
使用帮助:
常见问题:
本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
前言: 首先你要明白, 所谓的第三方登录,就是利用用户在第三方平台上已有的账号来快速完成自己应用的登录或者注册的功能。而这里的第三方平台,一般是已经有大量用户的平台,如国内的新浪微博、QQ空间,微信,外国的Facebook、twitter等等。第三方登录不是一个具体的接口,而是一种思想或者一套步骤。这种集成三方的东西, 都非常简单,可能会有坑, 填上就好, 这篇文章以微博为例, 其实都是一样的. 步骤或繁或简单, 习惯就好. 具体请点击我简书的原文 原文链接
需求:一半搜索界面上都会有热门搜索(我其他的博客有介绍),搜索的历史记录等等,今天这里分析历史记录的写,和存 *效果图 如图整体是一个Listview,头布局是从 搜索历史 文字开始到热门搜索是整个头布局,中间一个listview显示历史记录, 脚布局 用来处理清楚历史记录的操作,在这里使用的是sp来进行缓存的(只存了10条数据) 下面贴的代码 具体的需求具体分析,这里是写出读取,和写入记入的方法,更具需求在灵活调用即可 (1):读取历史 SharePreferenceUtil.SPACE_HISTORY
6月24日,2016AppCan移动开发者大会在北京国际会议中心盛大举行。大会以“平台之上,应用无限”为主题,全景展现AppCan移动技术蓝图和80万AppCan开发者的移动双创实践成果,并重磅发布全新产品企业移动门户——正益工作,并宣布面向开发者/合作伙伴/企业客户开源开放,全面推助开发者技术变现、加速企业移动化转型。 技术与生态共进,本届大会不仅是AppCan的技术盛会,也是移动互联网行业的盛宴:华为、科大讯飞、TalkingData、听云等20余家国内顶尖的移动互联网企业参展;东方航空、我爱我家以及
Android中的AMS想必是做android开发的工程师耳熟能详的系统级别的服务,但是它又是如此地庞大(单单ActivityManagerService.java文件就2W+行代码),因此我们在学习它的时候总是不能找到实际的主线,很是混乱。这里我会连续写几篇文章从它的启动过程,主要业务逻辑,和别的模块之间的互操作逻辑等角度来向大家简单介绍一下它。这里我只能是抛砖引玉,简单介绍,不会面面俱到,因为AMS的代码量确实比较大,如果向大家一一道来,想必大家一定会厌烦而且学习效果不好。希望大家在阅读本文的时候,同
阅读前可以先看 Android自定义图表:ChartView 需求: 通过以上例子我们修改测试数据后,拿到的View图像是这样的: 而我们要的效果是纵坐标7.45以上与5.97以下的部分为红色,7.45与6.43间为绿色,6.18与6.43之间为黄色,效果如下: 有了解自定义View的同学应该清楚从一个点画到另一个点的过程中,通过Paint与canvas.drawLine()绘制一条不同颜色的线是很不容易做到的,如果分成两条不同的线,无疑是更加增大了怎个绘制过程的复杂度。 那么我们如何去做成下图的这种效果
Android学习笔记十二之Android基础UI三 ScrollView滚动视图 ScrollView是继承于FrameLayout,也是一个显示容器,由于手机屏幕是有限的,当需要组件安排多组信息的时候,ScrollView可以安排这些组件,我们浏览的时候可以进行滑动操作,滚动显示。但是,需要注意的是,ScrollView只能包含一种组件。 实现代码: @Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) { supe
基本定义 Observable – 被观察者(事件源) Observer – 观察者 Creating Observables(创建操作) 以下展示了创建Observable的各种方法 Create — 通过observer的方法创建一个新的Observable Defer — 直到observer订阅的时候才会创建这个Observable,并且为每一个observer创建一个Observable Empty/Never/Throw — 创建行为受限特殊的Observable Empty — 只会发射on
博主这个系列的文章 React Native开发之IDE(Atom+Nuclide) React Native开发之FlexBox代码+图解 React Native的Navigator详解 另外,我在Github上建立了一个仓库来搜集优秀的React Native库和优秀的博客等 ReactNativeMaterials 资料 官方关于动画的介绍 官方给出的复杂动画的示例 开源项目react-native-animatable React Native Animation Book 可以用在实际项目里的
这篇文章里,我们将会讨论一些 iOS 和 OS X 都可以使用的底层 API。除了
dispatch_once
,我们一般不鼓励使用其中的任何一种技术。 但是我们想要揭示出表面之下深层次的一些可利用的方面。这些底层的 API 提供了大量的灵活性,随之而来的是大量的复杂度和更多的责任。在我们的文章 常见的后台实践 中提到的高层的 API 和模式能够让你专注于手头的任务并且免于大量的问题。通常来说,高层的 API 会提供更好的性能,除非你能承受起使用底层 API 带来的纠结于调试代码的时间和努力。 尽管如
前言 本文将演示一个iOS客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo 。服务端将分别用MINA2和Netty4进行实现,而通信时服务端你只需选其一就行了。同时用MINA2和Netty4分别实现服务端的目的,是因为很多人都在纠结到底是用MINA还是Netty来实现高并发的Java网络通信服务端,在此干脆两个都实现了,就看你怎么选择了,够吊吧。 NIO框架的流行,使得开发大并发、高性能的互联网服务端成为可能。这其中最流行的无非就是MINA和Netty了,MINA目
Copyright (C)
ITfish.net求教:如何在手机上显示fps和drawCalls次数呢?【unity3d吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:79,317贴子:
求教:如何在手机上显示fps和drawCalls次数呢?收藏
在pc上发布是有这个的,到手机上就消失了呢?
VRStar unity3d,名师一对一辅导,带你触碰前沿VR技术.一流的教学环境和VR学习体验,VRStar您正确的选择!
fps有显示,网上有代码,drawcall你电脑是多少,发布出来也是那么多,不会变的
登录百度帐号推荐应用Unity3d开发(十一)编辑器DrawCall参数详细介绍
对于Unity运行场景中,有许多可以标记场景状况的参数。这篇文章主要探讨这些参数的意义,其中如果有错误欢迎指正。
Game Stats
点击游戏Tab下的Stats可以展开如下界面,可以方便我们查看游戏运行状态。
FPS是通常说的帧率。每帧用时指的是渲染一帧需要消耗的用时,这个值只包含每帧更新游戏视图的时间,不受其他在编辑器中功能的影响,例如Profiler。FPS是这个数字的倒数。值得注意的是,这个值会比我们通常说的帧率要高,因为我们是直接计算两帧之间的时间差的。我猜想手机打包之后两个值的差会变小,但也不会绝对一样。
Batches & DrawCall
这个是绘制图像的重要指标,可以作为衡量场景绘制效率的首要参考。
一个 Draw Call,等于呼叫一次 DrawIndexedPrimitive (DX) or glDrawElements (OGL),等于一个 Batch。
NVIDIA 在GDC上曾提出 25k batch/sec的渲染量会使1GHz的CPU达到100%的使用率,因此使用公式
25K?n(GHZ)?Percentage/Framerate=Batch/Frame
可以推算出某些CPU可以抗多少Batch。例如红米手机CPU为1.5GHz,假设分出20%资源供渲染,希望游戏跑到30帧。那么能抗多少DrawCall? 25k * 1.5 * 0.2 / 30 = 250。因此从这方面也能看出,如果CPU不能分出更多的资源供渲染计算,能抗的DrawCall就会变少。
在Stats面板中看到的Batches是渲染的总Batch这个值等于同于DrawCall。但Unity中可以获取到未批次处理之前的DrawCall。因此需要注意不要混淆概念。
Saved By Batching
这个值是由于Batch减少的DrawCall,可以间接的看到场景优化的效果。这个值由两部分组成:Static Batching和Dynamic Batching。这个由Unity内建自动合并虽然优点多多,但也不是没有缺陷。静态合并会引发内存和存储的额外开销,动态合并会增加CPU的负担。 这部分内容参考
总体上讲所以希望批次渲染的元素要有相同的材质。通常两个材质如果只有贴图不同,可以将贴图合并到一张大图中,这就是所谓的。另外在使用ShadowCaster时,只要材质相同,即使贴图不同也可以合并渲染。
Dynamic Batches
动态合并在满足以下条件时是自动完成的:
模型总顶点数小于900。不包含镜像transform改变。不改变Scale。如果使用动态lightmap需要指定正确。不使用多Pass的Shader.
由于需要在合并时通过CPU计算转为世界坐标,这项技术只在CPU消耗比DrawCall消耗&便宜&时才值得。这个衡量标准会根据平台产生差异,例如苹果平台上DrawCall的消耗便宜,就不应该使用这项技术。这个功能可以在Editor-&Project Setting-&Player中进行设置打开与关闭。
Static Batches
场景中不能移动的物件可以使用静态合并,它不受顶点数的限制,可以大幅减少DrawCall。但为了将元素合并到一个大模型中,这项技术需要额外的内存。主要的内存消耗在于共享多边形会在内存中重复创建。因此有时候需要牺牲渲染效率来避免静态合并,来保证内存够小。例如在茂密的树林中使用这项技术会导致大量的内存消耗。
Tris & Verts
摄像机下的所有三角形和顶点这个在低端硬件上也是主要瓶颈。
脚本获取值
其他数据暂时先不关注了,有必要以后可以再单写一篇。在编辑模式下这些数据是可以通过脚本获取到的,不过打出包来不太成。简单写了一下,效果如下:
vczlyrnTw76yzKy6z7Kio6zD5sasyrnTw7avzKy6z7KioaOzob6wVUnSu7myMTe49kJhdGNooaO2r8ysxfq0zjG49qOsvrLMrMX6tM4yuPajqLK71qqy8LfWuebU8qOpo6zF+rTO5NbIvtK7ubIyMKGjw7/Su7j2tq/MrM7vzOUxuPZEcmF3Q2FsbKOsubIyMLj2o6w0uPa2r8yszu/M5TG49kRyYXdDYWxso6wxN7j2VUmy+sn6tcREcmF3Q2FsbKOsubIzOLj2oaM8L3A+DQo8cD7P4LnYtPrC68jnz8KjujwvcD4NCjxwcmUgY2xhc3M9"brush:">
using UnityE
using System.C
using UnityE
public class testDC : MonoBehaviour
#region Unity Messages
void OnGUI()
GUILayout.TextField(&Total DrawCall: & + UnityStats.drawCalls);
GUILayout.TextField(&Batch: & + UnityStats.batches);
GUILayout.TextField(&Static Batch DC: & + UnityStats.staticBatchedDrawCalls);
GUILayout.TextField(&Static Batch: & + UnityStats.staticBatches);
GUILayout.TextField(&DynamicBatch DC: & + UnityStats.dynamicBatchedDrawCalls);
GUILayout.TextField(&DynamicBatch: & + UnityStats.dynamicBatches);
GUILayout.TextField(&Tri: & + UnityStats.triangles);
GUILayout.TextField(&Ver: & + UnityStats.vertices);
#endregion扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
当前位置: &
查看: 1602|回复: 1
Unity3D Drawcall的一些测试(二十三)
61096/1500排名<font color="#FF昨日变化9主题帖子积分
蛮牛粉丝, 积分 1096, 距离下一级还需 404 积分
蛮牛粉丝, 积分 1096, 距离下一级还需 404 积分
在线时间374 小时
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
才可以下载或查看,没有帐号?
Draw call一般包含了要画什么(点/线/三角形),顶点数据在哪里(显存地址),是怎么组织的。图形API把draw call丢给驱动,驱动丢给GPU前端,GPU开始解释并执行。单个Draw call的代价本身并不大,但提交的任务可大可小,如果用大量的draw call每次提交少量任务,那么就来了,原因在于GPU处理任务的速度可能会大于CPU提交任务的速度,导致pipeline经常空闲下来。要优化有两种办法,一是合并任务,减少提交次数,二是改革图形API和驱动,进一步减少单个Draw call的代价,比如避免频繁的context switch而是采用多个任务提交队列,并发挥多核CPU优势,优化提交任务速度。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
以下是个人做的测试
Drawcall的限制和cpu之间的关系:
Fps是指游戏运行时的帧率,表示每秒要绘制多少帧,一般要让游戏保持肉眼可见的流畅度需要保持在30帧以上,而每帧可能会有多次渲染,(cpu告诉GPU场景中需要渲染哪些物件,物件的材质,顶点,图片等信息,即一次Drawcall),Batches代表每帧有多少次Drawcall(即渲染多少次)。
NVIDIA 在 GDC 曾提出,25K batchs/sec 会吃满 1GHz 的 CPU,100的使用率。所以他们推出了一条公式,来预估游戏中大概可以 Run 多少个 Batch:
举个例子:如果你的目标是游戏跑30FPS、使用2GHz的CPU、20%的工作量拨给Draw Call来使用,那你每帧可以有多少Draw Call呢?
<font color="#3 Batchs/Frame = 25K * 2 * (0.2/30)
假设在800Mhz的iTouch5中,如果目标游戏跑30fps,cpu 20%的工作量拨给drawcall,那么可以有多少drawcall呢?&&
<font color="#k*0.8*(0.2/30)=133.3.
在iTouch5上实际测试数据:
Drawcall& && && && && && && && && && && && && && && && &CPU
<font color="#& && && && && && && && && && && && && && && && && && && && && & 23%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 23%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 23%--24%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 24%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 24%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 24%--25%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 24%--25%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 25%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 25%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 34%
<font color="#& && && && && && && && && && && && && && && && && && && && && & 37%
<font color="#0& && && && && && && && && && && && && && && && && && && && && & 44%
<font color="#0& && && && && && && && && && && && && && && && && && && && && & 100%
从上面数据可以得到:在30fps的游戏中没1%的CPU使用率大概能承载4.6左右的drawcall(370-4)/(100-23)=4.7.就是说20%的cpu大概能够承载20*4.6=95的DrawCall。理论数据2Ghz与0.8GHz相差2.56倍,333/2.56=130的drawCall,实际测试数据大概值为95(因为CPU占用率的值并不是稳定的,所以取相对比较稳定的值作为概值)。另外在发布的App中可能会有其他因素影响到CPU的工作状态,所以认为该公式的计算结果可以作为性能边界的估值,并不是精确值。
IPhone6的CPU频率为1.4Ghz,所以游戏跑30fps,20%的CPU使用,每帧可以跑的DrawCall数为:25k*1.4*(0.2/30)=233。(概值)
那既然 Batch 是个箱子,里头装着物件的顶点资料,再依据我们上面的描述,那表示同
材质或 Shader 的物件,可以合并成一个 Batch 送往 GPU,这样就是最省事的方法!
Unity在 Player Setting 里的两个功能选项 Static Batching 与 Dynamic Batching。功能描述如下:
<font color="#.& && &&&Static Batching 是将标明为 Static 的静态物件,如果在使用相同材质球的条件下,Unity 会自动帮你把这两个物件合并成一个 Batch,送往 GPU 来处理。这功能对效能上非常的有帮助,所以是需要付费才有的。
<font color="#.& && &&&Dynamic Batching 是在物件小于300面的条件下(不论物件是否为静态或动态),在使用相同材质球下,Unity就会自动帮你合合并成一个 Batch 送往 GPU 来处理。
Unity对Drawcall的一些优化:
在屏幕上渲染物体,引擎需要发出一个绘制调用来访问图形API(iOS系统中为OpenGL ES)。每个绘制调用需要进行大量的工作来访问图形API,从而导致了CPU方面显著的性能开销。
Unity在运行时可以将一些物体进行合并,从而用一个绘制调用来渲染他们。这一操作,我们称之为“批处理”。一般来说,Unity批处理的物体越多,你就会得到越好的渲染性能。
Unity中内建的批处理机制所达到的效果要明显强于使用几何建模工具(或使用Standard Assets包中的CombineChildren脚本)的批处理效果。这是因为,Unity引擎的批处理操作是在物体的可视裁剪操作之后进行的。Unity先对每个物体进行裁剪,然后再进行批处理,这样可以使渲染的几何总量在批处理前后保持不变。但是,使用几何建模工具来拼合物体,会妨碍引擎对其进行有效的裁剪操作,从而导致引擎需要渲染更多的几何面片。
只有拥有相同材质的物体才可以进行批处理。因此,如果你想要得到良好的批处理效果,你需要在程序中尽可能地复用材质和物体。
如果你的两个材质仅仅是纹理不同,那么你可以通过 纹理拼合 操作来将这两张纹理拼合成一张大的纹理。一旦纹理拼合在一起,你就可以使用这个单一材质来替代之前的两个材质了。
如果你需要通过脚本来访问复用材质属性,那么值得注意的是改变Renderer.material将会造成一份材质的拷贝。因此,你应该使用Renderer.sharedMaterial来保证材质的共享状态。
动态批处理
如果动态物体共用着相同的材质,那么Unity会自动对这些物体进行批处理。
动态批处理操作是自动完成的,并不需要你进行额外的操作。
<font color="#、 批处理动态物体需要在每个顶点上进行一定的开销,所以动态批处理仅支持小于900顶点的网格物体。
<font color="#、 如果你的着色器使用顶点位置,法线和UV值三种属性,那么你只能批处理300顶点以下的物体;如果你的着色器需要使用顶点位置,法线,UV0,UV1和切向量,那你只能批处理180顶点以下的物体。
<font color="#、请注意:属性数量的限制可能会在将来进行改变。
<font color="#、 不要使用缩放尺度(scale)。分别拥有缩放尺度(1,1,1)和(2,2,2)的两个物体将不会进行批处理。
<font color="#、 统一缩放尺度的物体不会与非统一缩放尺度的物体进行批处理。
使用缩放尺度(1,1,1)和 (1,2,1)的两个物体将不会进行批处理,但是使用缩放尺度(1,2,1)和(1,3,1)的两个物体将可以进行批处理。
<font color="#、 使用不同材质的实例化物体(instance)将会导致批处理失败。
<font color="#、拥有lightmap的物体含有额外(隐藏)的材质属性,比如:lightmap的偏移和缩放系数等。所以,拥有lightmap的物体将不会进行批处理(除非他们指向lightmap的同一部分)。
<font color="#、 多通道的shader会妨碍批处理操作。比如,几乎unity中所有的着色器在前向渲染中都支持多个光源,并为它们有效地开辟多个通道
<font color="#、预设体的实例会自动地使用相同的网格模型和材质。
静态批处理
相对而言,静态批处理操作允许引擎对任意大小的几何物体进行批处理操作来降低绘制调用(只要这些物体不移动,并且拥有相同的材质)。因此,静态批处理比动态批处理更加有效,你应该尽量低使用它,因为它需要更少的CPU开销。
为了更好地使用静态批处理,你需要明确指出哪些物体是静止的,并且在游戏中永远不会移动、旋转和缩放。想完成这一步,你只需要在检测器(Inspector)中将Static复选框打勾即可,如下图所示:
使用静态批处理操作需要额外的内存开销来储存合并后的几何数据。在静态批处理之前,如果一些物体共用了同样的几何数据,那么引擎会在编辑以及运行状态对每个物体创建一个几何数据的备份。这并不总是一个好的想法,因为有时候,你将不得不牺牲一点渲染性能来防止一些物体的静态批处理,从而保持较少的内存开销。比如,将浓密森里中树设为Static,会导致严重的内存开销。
如何对动态加载的静态物体进行静态合批操作:
GameObject go = (GameObject)Instantiate(gameObjectObj, Vector3.right * 4 + Vector3.left * 2 * l, Quaternion.LookRotation(Vector3.up, Vector3.forward));
go.isStatic =//将实例化的物体设置为静态
go.transform.parent = root.
gosList.Add(go);
gos = gosList.ToArray();
bine(gos, root);静态合并
unity drawcall是什么;unity batches多少;batching 3d;ununity 点光源unity3d 5.23 迅雷下载;drawcall 不合并原因;unity静态批处理没有效果;unity 地形unity 一个粒子系统占几个unity动态合批;unity batches啥意思;unity batches
每日推荐:
3205/300排名<font color="#FF昨日变化11主题帖子积分
偶尔光临, 积分 205, 距离下一级还需 95 积分
偶尔光临, 积分 205, 距离下一级还需 95 积分
在线时间110 小时
每日推荐:

我要回帖

更多关于 unity drawcall 查看 的文章

 

随机推荐