如何降低Unity程序的unity5 drawcalll

浅谈Draw Call和Batch的区别 | Unity3D教程手册
当前位置 :
» 浅谈Draw Call和Batch的区别
浅谈Draw Call和Batch的区别
开发游戏时,一定被时时提醒要减少 Draw Call,当然Unity也不例外,打开Game Window里的 Stats,可以看到 Draw Call 与 Batched 的数字。但到底什么是 Draw Call?影响的效能是来自 CPU?还是 GPU?
浅谈Draw Call和Batch的区别
首先,让我们定义何为 “Draw Call”:
“一个 Draw Call,等于呼叫一次 DrawIndexedPrimitive (DX) or glDrawElements (OGL),等于一个 Batch”
摸过 DirectX 或 OpenGL 的人来说,对 DrawIndexedPrimitive 与 glDrawElements 这
API 一定不陌生。当我们准备好资料 (通常为三角面的顶点资讯) 要 GPU 划出来时,一定得呼叫这个函式。换句话说,如果在画面上有一张 “木"
椅子、一张 “铁" 桌子,那理论上就会有两个 Draw Call。
有看到特别点出 “木" 与 “铁" 吗?这代表两物件是使用不同材质球或者不同的 Shader。在 DirectX 或 OpenGL
里,对不同物件指定不同贴图或不同 Shader 的描述,就会需要呼叫两次Draw Call。Procedure code如下:
&&&1SetShader( “Diffuse" );2SetTexture( “铁" );3DrawPrimitive( DeskVertexBuffer );4&5SetShader( “VertexLight"&);6SetTexture( “木" );7DrawPrimitive( ChairVertexBuffer );
每次对 Shader 的更动或者贴图的更动,基本上就是对 Rendering Pipeline 的设定做修改,所以需要不同的 Draw
Call 来完成物件的绘制。现在了解为什么 Unity 官方文件里,老是要你尽量使用同样材质球,以减少 Draw Call 数量了吧!
再来谈到 Batch,其实也是 Draw Call 的另一种称呼。你可以想成每一次的 Draw Call 会产生一个 Batch,而
Batch 里装的是物件顶点资料,Batch 由 CPU 透过 “驱动程式” 将顶点资料送往
GPU,GPU接手后将物件画在画面上。由此可知,越多 Draw Call,CPU 就越忙碌。这下更清楚知道 Draw Call 数量所影响的是
CPU 效能而非 GPU。
NVIDIA 在 GDC 曾提出,25K batchs/sec 会吃满 1GHz 的 CPU,100的使用率。所以他们推出了一条公式,来预估游戏中大概可以 Run 多少个 Batch:
浅谈Draw Call和Batch的区别
举个例子:如果你的目标是游戏跑30FPS、使用2GHz的CPU、20š„工作量拨给Draw Call来使用,那你每秒可以有多少Draw Call呢?
&333 Batchs/Frame = 25K * 2 * (0.2/30)
那既然 Batch 是个箱子,里头装着物件的顶点资料,再依据我们上面的描述,那表示同样材质或 Shader 的物件,可以合并成一个 Batch 送往 GPU,这样就是最省事的方法!
Unity在 Player Setting 里的两个功能选项 Static Batching 与 Dynamic Batching。功能描述如下:
Static Batching 是将标明为 Static 的静态物件,如果在使用相同材质球的条件下,Unity 会自动帮你把这两个物件合并成一个 Batch,送往 GPU 来处理。这功能对效能上非常的有帮助,所以是需要付费才有的。
Dynamic Batching 是在物件小于300面的条件下(不论物件是否为静态或动态),在使用相同材质球下,Unity就会自动帮你合合并成一个 Batch 送往 GPU 来处理。
根据上述的说明,相信大家对降低 Draw Call 这件事有更深一层的认识吧!还有什么不清楚或者错误的地方,还请大家能够留言回复。
相关文章:
【上一篇】
【下一篇】
您可能还会对这些文章感兴趣!给我们留言
地址:福建省晋江市青阳街道洪山路国际工业设计园纳金网
电话:086-595--067-39199
(周一到周五,
周六周日休息)
查看: 18105|回复: 16
最后登录注册时间阅读权限90积分30810
资深设计师, 积分 30810, 距离下一级还需 19190 积分
纳金币31124 精华66
最简单的优化建议:
1.PC平台的话保持场景中显示的顶点数少于200K~3M,移动设备的话少于10W,一切取决于你的目标GPU与CPU。
2.如果你用U3D自带的SHADER,在表现不差的情况下选择Mobile或Unlit目录下的。它们更高效。
3.尽可能共用材质。
4.将不需要移动的物体设为Static,让引擎可以进行其批处理。
5.尽可能不用灯光。
6.动态灯光更加不要了。
7.尝试用压缩贴图格式,或用16位代替32位。
8.如果不需要别用雾效(fog)
9.尝试用OcclusionCulling,在房间过道多遮挡物体多的场景非常有用。若不当反而会增加负担。
10.用天空盒去“褪去”远处的物体。
11.shader中用贴图混合的方式去代替多重通道计算。
12.shader中注意float/half/fixed的使用。
13.shader中不要用复杂的计算pow,sin,cos,tan,log等。
14.shader中越少Fragment越好。
15.注意是否有多余的动画脚本,模型自动导入到U3D会有动画脚本,大量的话会严重影响消耗CPU计算。
16.注意碰撞体的碰撞层,不必要的碰撞检测请舍去。
1.为什么需要针对CPU(中央处理器)与GPU(图形处理器)优化?
CPU和GPU都有各自的计算和传输瓶颈,不同的CPU或GPU他们的性能都不一样,所以你的游戏需要为你目标用户的CPU与GPU能力进行针对开发。
2.CPU与GPU的限制
GPU一般具有填充率(Fillrate)和内存带宽(Memory Bandwidth)的限制,如果你的游戏在低质量表现的情况下会快很多,那么,你很可能需要限制你在GPU的填充率。
CPU一般被所需要渲染物体的个数限制,CPU给GPU发送渲染物体命令叫做DrawCalls。一般来说DrawCalls数量是需要控制的,在能表现效果的前提下越少越好。通常来说,电脑平台上DrawCalls几千个之内,移动平台上DrawCalls几百个之内。这样就差不多了。当然以上并不是绝对的,仅作一个参考。
往往渲染(Rendering)并不是一个问题,无论是在GPU和CPU上。很可能是你的脚本代码效率的问题,用Profiler查看下。
关于Profiler介绍:http://docs..com/Documentation/Manual/Profiler.html
需要注意的是:
在GPU中显示的RenderTexture.SetActive()占用率很高,是因为你同时打开了编辑窗口的原因,而不是U3D的BUG。
3.关于顶点数量和顶点计算
CPU和GPU对顶点的计算处理都很多。GPU中渲染的顶点数取决于GPU性能和SHADER的复杂程度,一般来说,每帧之内,在PC上几百万顶点内,在移动平台上不超过10万顶点。
CPU中的计算主要是在蒙皮骨骼计算,布料模拟,顶点动画,粒子模拟等。GPU则在各种顶点变换、光照、贴图混合等。
【个人认为,具体还是看各位的项目需求,假设你项目的是<font color="#d游戏。你游戏需要兼容低配置的硬件、流畅运行、控制硬件发热的话,还要达到一定效果(LIGHTMAP+雾效),那么顶点数必定不能高。此时同屏2W顶点我认为是个比较合适的数目,DRAWCALL最好低于70。另,控制发热请控制最高上限的帧率,流畅的话,帧率其实不需要太高的。】
4.针对CPU的优化——减少DRAW CALL 的数量
为了渲染物体到显示器上,CPU需要做一些工作,如区分哪个东西需要渲染、区分开物体是否受光照影响、使用哪个SHADER并且为SHADER传参、发送绘图命令告诉显示驱动,然后发送命令告诉显卡删除等这些。
假设你有一个上千三角面的模型却用上千个三角型模型来代替,在GPU上花费是差不多的,但是在CPU上则是极其不一样,消耗会大很多很多。为了让CPU更少的工作,需要减少可见物的数目:
a.合并相近的模型,手动在模型编辑器中合并或者使用UNITY的Draw call批处理达到相同效果(Draw call batching)。具体方法和注意事项查看以下链接:
Draw call batching : /Documentation/Manual/DrawCallBatching.html
b.在项目中使用更少的材质(material),将几个分开的贴图合成一个较大的图集等方式处理。
如果你需要通过脚本来控制单个材质属性,需要注意改变Renderer.material将会造成一份材质的拷贝。因此,你应该使用Renderer.sharedMaterial来保证材质的共享状态。
有一个合并模型材质不错的插件叫Mesh Baker,大家可以考虑试下。
c.尽量少用一些渲染步骤,例如reflections,shadows,per-pixel light 等。
d.Draw call batching的合并物体,会使每个物体(合并后的物体)至少有几百个三角面。
假设合并的两个物体(手动合并)但不共享材质,不会有性能表现上的提升。多材质的物体相当于两个物体不用一个贴图。所以,为了提升CPU的性能,你应该确保这些物体使用同样的贴图。
另外,用灯光将会取消(break)引擎的DRAW CALL BATCH,至于为什么,查看以下:
Forward Rendering Path Details:
/Documentation/Components/RenderTech-ForwardRendering.html
e.使用相关剔除数量直接减少Draw Call数量,下文有相关提及。
5.优化几何模型
最基本的两个优化准则:
a.不要有不必要的三角面。
b.UV贴图中的接缝和硬边越少越好。
需要注意的是,图形硬件需要处理顶点数并跟硬件报告说的并不一样。不是硬件说能渲染几个点就是几个点。模型处理应用通展示的是几何顶点数量。例如,一个由一些不同顶点构成的模型。在显卡中,一些集合顶点将会被分离(split)成两个或者更多逻辑顶点用作渲染。如果有法线、UV坐标、顶点色的话,这个顶点必须会被分离。所以在游戏中处理的实际数量显然要多很多。
6.关于光照
若不用光肯定是最快的。移动端优化可以采用用光照贴图(Lightmapping)去烘培一个静态的贴图,以代替每次的光照计算,在U3D中只需要非常短的时间则能生成。这个方法能大大提高效率,而且有着更好的表现效果(平滑过渡处理,还有附加阴影等)。
在移动设备上和低端电脑上尽量不要在场景中用真光,用光照贴图。这个方法大大节省了CPU和GPU的计算,CPU得到了更少的DRAWCALL,GPU则需要更少顶点处理和像素栅格化。
Lightmapping : /Documentation/Manual/Lightmapping.html
7.对GPU的优化——图片压缩和多重纹理格式
Compressed Textures(图片压缩):
/Documentation/Components/class-Texture2D.html
图片压缩将降低你的图片大小(更快地加载更小的内存跨度(footprint)),而且大大提高渲染表现。压缩贴图比起未压缩的32位RGBA贴图占用内存带宽少得多。
之前U3D会议还听说过一个优化,贴图尽量都用一个大小的格式(512 * 512 , 1024 * 1024),这样在内存之中能得到更好的排序,而不会有内存之间空隙。这个是否真假没得到过测试。
MIPMA(多重纹理格式):
/Documentation/Components/class-Texture2D.html
跟网页上的略缩图原理一样,在3D游戏中我们为游戏的贴图生成多重纹理贴图,远处显示较小的物体用小的贴图,显示比较大的物体用精细的贴图。这样能更加有效的减少传输给GPU中的数据。
8.LOD 、 Per-Layer Cull Distances 、 Occlusion Culling
LOD (Level Of Detail) 是很常用的3D游戏技术了,其功能理解起来则是相当于多重纹理贴图。在以在屏幕中显示模型大小的比例来判断使用高或低层次的模型来减少对GPU的传输数据,和减少GPU所需要的顶点计算。
摄像机分层距离剔除(Per-Layer Cull Distances):为小物体标识层次,然后根据其距离主摄像机的距离判断是否需要显示。
遮挡剔除(Occlusion Culling)其实就是当某个物体在摄像机前被另外一个物体完全挡住的情况,挡住就不发送给GPU渲染,从而直接降低DRAW CALL。不过有些时候在CPU中计算其是否被挡住则会很耗计算,反而得不偿失。
以下是这几个优化技术的相关使用和介绍:
Level Of Detail :
/Documentation/Manual/LevelOfDetail.html
Per-Layer Cull Distances :
/Documentation/ScriptReference/Camera-layerCullDistances.html
Occlusion Culling :
/Documentation/Manual/OcclusionCulling.html
9.关于Realtime Shadows(实时阴影)
实时阴影技术非常棒,但消耗大量计算。为GPU和CPU都带来了昂贵的负担,细节的话参考下面:
/Documentation/Manual/Shadows.html
10.对GPU优化:采用高效的shader
a.需要注意的是有些(built-in)Shader是有mobile版本的,这些大大提高了顶点处理的性能。当然也会有一些限制。
b.自己写的shader请注意复杂操作符计算,类似pow,exp,log,cos,sin,tan等都是很耗时的计算,最多只用一次在每个像素点的计算。不推荐你自己写normalize,dot,inversesqart操作符,内置的肯定比你写的好。
c.需要警醒的是alpha test,这个非常耗时。
d.浮点类型运算:精度越低的浮点计算越快。
在CG/HLSL中--
float :32位浮点格式,适合顶点变换运算,但比较慢。
half:16位浮点格式,适合贴图和UV坐标计算,是highp类型计算的两倍。
fixed: 10位浮点格式,适合颜色,光照,和其他。是highp格式计算的四倍。
写Shader优化的小提示:
/Documentation/Components/SL-ShaderPerformance.html
11.另外的相关优化:
a.对Draw Call Batching的优化
/Documentation/Manual/DrawCallBatching.html
b.对Rendering Statistics Window的说明和提示:
/Documentation/Manual/RenderingStatistics.html
c.角色模型的优化建议
用单个蒙皮渲染、尽量少用材质、少用骨骼节点、移动设备上角色多边形保持在300~1500内(当然还要看具体的需求)、PC平台上内(当然还要看具体的需求)。
/Documentation/Manual/ModelingOptimizedCharacters.html
最后登录注册时间阅读权限90积分6667
高级设计师, 积分 6667, 距离下一级还需 3333 积分
纳金币2715 精华0
Thanks for sharing this !
最后登录注册时间阅读权限90积分5672
高级设计师, 积分 5672, 距离下一级还需 4328 积分
纳金币7252 精华0
Thanks for sharing !
最后登录注册时间阅读权限10积分76
设计初学者, 积分 76, 距离下一级还需 24 积分
纳金币0 精华0
谢谢分享。。。支持了!!
最后登录注册时间阅读权限70积分3447
中级设计师, 积分 3447, 距离下一级还需 1553 积分
纳金币117 精华0
最后登录注册时间阅读权限70积分3154
中级设计师, 积分 3154, 距离下一级还需 1846 积分
纳金币1065 精华0
感谢分享!!!
最后登录注册时间阅读权限20积分457
设计实习生, 积分 457, 距离下一级还需 43 积分
纳金币10 精华0
非常中肯的建议,谢谢楼主分享
最后登录注册时间阅读权限30积分845
初级设计师, 积分 845, 距离下一级还需 155 积分
纳金币1 精华0
感谢分享哦~~~~想多问下手机上用fog会很费吗
能不能介绍下那个原理
最后登录注册时间阅读权限30积分704
初级设计师, 积分 704, 距离下一级还需 296 积分
纳金币261 精华0
最后登录注册时间阅读权限20积分375
设计实习生, 积分 375, 距离下一级还需 125 积分
纳金币95 精华0
站长推荐 /1
纳金名模第108期路标3d模型:数量30个,大小为128MB。完全免费下载哦!这样的福利我和我的小伙伴们都惊呆了!!下载地址:
400-067-3919
Powered by - X2.5
Narkii Inc.&&国之画&&&&&&
版权所有 京ICP备号-2
迷上了代码!如何降低Unity程序的Drawcall_百度知道
如何降低Unity程序的Drawcall
我有更好的答案
DrawCall优化合并,即DrawCall Batching. 通过减少Draw call数 和对显卡性能的消耗来提高性能。
一 Mesh Renderer
分为Dynamic Batching和 Static Batching
Dynamic Batching
不需要任何操作,只要共享材质(即使是不同的Mesh模型也可以),就会自动被合并。可以自由移动旋转。但有以下使用要求:
(1) 模型文件共计点数不超过900。(重复使用同一个Mesh不计)
(2) 单个物体可以不超过300点,Shader可以有法线UV。
但如果Shader使用了 UV0 UV1两套UV,或者Tangent切线的话,单个物体只能不超过180点
(3)游戏对象使用相同模型和材质时,只有相同缩放(即xyz等比缩放,浮点尾数可以有细微差)的会被合并。
(1,1,1)与(1,1,1)
(2,2,2)与(2,2,2)
(0.5,0.5,0.5)与 (0.5,0.5,0.5...
其他类似问题
为您推荐:
unity的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁unity 最后一次drawcall 如何避免?
各位渲染老司机:unity5跟unity4比较,渲染管线有了更改。通过Adreno观察,发现 unity在调用glClear后会创建一个framebuffer绑定上去。最后会在把framebuffer blit到默认的framebuffer上去。在像素填充率比较差同时分辨率较高的机型挺影响应能的。大概差10帧左右。所以想问各位老司机,有什么思路避免这个吗?(我现在思路是一开始把framebuffer绑成默认的,然后更改最后那次draw的VertexShader,但是shader替换成功了,frameBuffer unity会在我调用完后恢复状态,重新绑定成新生成的。然后考虑替换openGl函数指针,但是感觉无从下手。android系统层有持有函数指针的变量,但是外围访问不到。其他暂时想不到思路。)求各位大牛指点迷津。
按投票排序
这个我还真研究过……当时在官方论坛问过这个事情 官方的意思是不好避免,主要是版本适配和各种dirty fix...所以我最后放弃节约这个了 I dont remember fully honestly but i believe the main reasons for it were to workaround LOTS of egl context bugs/issues/"features". For example - starting with some android version lots of phones started to have the feature of "please use framebuffer directly in compositor" meaning your backbuffer alpha would be used by OS to do alpha blending with views behind yours (or with simply black backgrounds)
我的想法和
的答案一样,这个东西是为了简化unity本身的开发,上层很难避免。这么用framebuffer相当于有一个自己的back buffer,保证不会被别的东西碰到。之后再把它刷到系统的back buffer就是了。而在有些tile-based硬件上,切换render target非常慢,有可能有个高达1ms的固定开销。在这种情况下,多一次切换很可能就让游戏到不了60fps了。这个修改的本质原因很可能是android的surface flinger。现在android的做法是app提供一个back buffer,surface flinger通过系统获得那张图,混合上UI的内容后画到屏幕。按说应该把这些都画到系统的back buffer,但为了降低能耗和提高性能,变成直接在那上面混合,并设定每一帧都不管里面的内容。不过即便如此,其实也不需要专门一个frame buffer,但unity的人偷懒了。
又掉坑里了……
之前电话unity问过类似问题 unity说现在手机硬件发展挺快的巴拉巴拉巴拉巴拉(°_°) 然后unity一生黑
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 unity5 drawcall 的文章

 

随机推荐