Unity3D - 性能优化之Draw Call
Unity(或者说基本所有图形引擎)生成一帧画面的处理过程大致可以这样简化描述:引擎首先经过简单的可见性测试,确定摄像机可以看到的物体,然后把这些物体的顶点(包括本地位置、法线、UV等),索引(顶点如何组成三角形),变换(就是物体的位置、旋转、缩放、以及摄像机位置等),相关光源,纹理,渲染方式(由材质/Shader决定)等数据准备好,然后通知图形API——或者就简单地看作是通知GPU——开始绘制,GPU基于这些数据,经过一系列运算,在屏幕上画出成千上万的三角形,最终构成一幅图像。
在Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call。这一过程是逐个物体进行的,对于每个物体,不只GPU的渲染,引擎重新设置材质/Shader也是一项非常耗时的操作。因此每帧的Draw Call次数是一项非常重要的性能指标,对于iOS来说应尽量控制在20次以内,这个值可以在编辑器的Statistic窗口看到。
Unity内置了Draw Call Batching技术,从名字就可以看出,它的主要目标就是在一次Draw Call中批量处理多个物体。只要物体的变换和材质相同,GPU就可以按完全相同的方式进行处理,即可以把它们放在一个Draw Call中。Draw Call Batching技术的核心就是在可见性测试之后,检查所有要绘制的物体的材质,把相同材质的分为一组(一个Batch),然后把它们组合成一个物体(统一变换),这样就可以在一个Draw Call中处理多个物体了(实际上是组合后的一个物体)。
但Draw Call Batching存在一个缺陷,就是它需要把一个Batch中的所有物体组合到一起,相当于创建了一个与这些物体加起来一样大的物体,与此同时就需要分配相应大小的内存。这不仅会消耗更多内存,还需要消耗CPU时间。特别是对于移动的物体,每一帧都得重新进行组合,这就需要进行一些权衡,否则得不偿失。但对于静止不动的物体来说,只需要进行一次组合,之后就可以一直使用,效率要高得多。
Unity提供了Dynamic Batching和Static Batching两种方式。Dynamic Batching是完全自动进行的,不需要也无法进行任何干预,对于顶点数在300以内的可移动物体,只要使用相同的材质,就会组成Batch。Static Batching则需要把静止的物体标记为Static,然后无论大小,都会组成Batch。如前文所说,Static Batching显然比Dynamic Batching要高效得多,于是,Static Batching功能是收费的……
要有效利用Draw Call Batching,首先是尽量减少场景中使用的材质数量,即尽量共享材质,对于仅纹理不同的材质可以把纹理组合到一张更大的纹理中(称为Texture Atlasing)。然后是把不会移动的物体标记为Static。此外还可以通过CombineChildren脚本(Standard Assets/Scripts/Unity Scripts/CombineChildren)手动把物体组合在一起,但这个脚本会影响可见性测试,因为组合在一起的物体始终会被看作一个物体,从而会增加GPU要处理的几何体数量,因此要小心使用。
对于复杂的静态场景,还可以考虑自行设计遮挡剔除算法,减少可见的物体数量同时也可以减少Draw Call。
总之,理解Draw Call和Draw Call Batching原理,根据场景特点设计相应的方案来尽量减少Draw Call次数才是王道,其它方面亦然。
Unity3D - 性能优化之Draw Call的更多相关文章
- Unity3D性能优化之Draw Call Batching
在屏幕上渲染物体,引擎需要发出一个绘制调用来访问图形API(iOS系统中为OpenGL ES).每个绘制调用需要进行大量的工作来访问图形API,从而导致了CPU方面显著的性能开销. Unity在运行时 ...
- (转)Unity3D - 性能优化之Draw Call
Unity(或者说基本所有图形引擎)生成一帧画面的处理过程大致可以这样简化描述:引擎首先经过简单的可见性测试,确定摄像机可以看到的物体,然后把这些物体的顶点(包括本地位置.法线.UV等),索引(顶点如 ...
- Unity3D性能优化--- 收集整理的一堆
http://www.cnblogs.com/willbin/p/3389837.html 官方优化文档--优化图像性能http://docs.unity3d.com/Documentation/Ma ...
- Unity3D 性能优化
Unity3D 性能优化 一.程序方面 01.务必删除脚本中为空或不需要的默认方法: 02.只在一个脚本中使用OnGUI方法: 03.避免在OnGUI中对变量.方法进行更新.赋值,输出变量建议在Upd ...
- Unity3D性能优化小tips——把this.transform缓存缓存起来
Unity3D开发时中有一个小tips,这在官方的文档里其实有提及的,但不那么显眼,这里小说一下: 在MonoBehaviour进行编程时,我们经常会用this.transform, this.gam ...
- Unity3D性能优化
一.美术资源优化 1.动态物体,角色.怪物.NPC (1)控制面的数量,300-2000个 (2)控制Skinner Mesh Renderer的数量,1个 (3)控制材质数量,1-3个 (4)控 ...
- Unity性能优化之 Draw Call原理<转>
Unity(或者说基本所有图形引擎)生成一帧画面的处理过程大致可以这样简化描述:引擎首先经过简单的可见性测试,确定摄像机可以看到的物体,然后把这些物体的顶点(包括本地位置.法线.UV等),索引(顶点如 ...
- Unity3D性能优化总结
一.程序方面 01.务必删除脚本中为空或不须要的默认方法: 02.仅仅在一个脚本中使用OnGUI方法. 03.避免在OnGUI中对变量.方法进行更新.赋值,输出变量建议在Update内. 04.同一脚 ...
- Unity性能优化之Draw Call(转)
Unity(或者说基本所有图形引擎)生成一帧画面的处理过程大致可以这样简化描述:引擎首先经过简单的可见性测试,确定摄像机可以看到的物体,然后把这些物体的顶点(包括本地位置.法线.UV等),索引(顶点如 ...
随机推荐
- C语言基础之自增自减运算符及注意事项
1.具体用法 1: int b; 2: int a = 10; 3: // b = 10 + 12; 4: //b = (a++) + (++a); 5: 6: // b = 11 + 11; 7: ...
- JAVA 线程池以及其他
http://www.cnblogs.com/dolphin0520/ http://www.cnblogs.com/absfree/category/801869.html
- git reset revert区别
git revert HEAD~1 撤销倒数第二次提交,并将这次操作作为一个新提交添加到log里,之前的提交历史不变,是撤销某次提交 git reset,直接回退到指定版本 git reset --s ...
- 在pos:a元素不设定宽度的情况下,他的最大宽度是受父元素的宽度所限制的。
<div style="width:80px;height:50px;position:relative;left:50px;"> <ul style=" ...
- MVC EasyUI 时间格式化
用 return Json(dr, JsonRequestBehavior.AllowGet); 会返回一个json 数据格式,在用 EasyUI 输出表格内容时会遇到时间输出不是我们想要的格式, ...
- 10g full join 优化
今天一个女生咨询我报名学优化.聊着聊着就让我优化一个sql 由于怕泄密,所以删除了 sql . 不好意思 该sql是 olap 的, 在oracle10g 上面跑.跑一次要33秒钟.一般olap报表. ...
- 对checkpoint not completed的理解
如果数据库存在两个日志组log1和log2,首先.-->log1-->log2-->log1,此时(log2切换到log1)触发checkpoint.该checkpoint will ...
- 【ecshop---新增包邮卡功能】
一:需求分析 项目组要求新增类似虚拟卡的包邮卡,用户获得包邮卡的方式包括后台发送和前台自助充值.包邮卡有使用期限.订单使用包邮卡免除邮费.可以和其他优惠活动同时进行! 二:开发功能点 后台:新增包邮卡 ...
- Java List序列化的实现
概述 java中的序列化与反序列化都要求对象实现Serializable接口(其实就是声明一下),而对于List这种动态改变的集合默认是不实现这个接口的,也就是不能直接序列化.但是数组是可以序列化的, ...
- [PWA] Disable Text Selection and Touch Callouts in a PWA on iOS
Because an installed PWA is really just a web app running in a browser, there are some browser behav ...