Unity性能优化-DrawCall
1. DrawCall是啥?其实就是对底层图形程序(比如:OpenGL ES)接口的调用,以在屏幕上画出东西。所以,是谁去调用这些接口呢?CPU。比如有上千个物体,每一个的渲染都需要去调用一次底层接口,而每一次的调用CPU都需要做很多工作,那么CPU必然不堪重负。但是对于GPU来说,图形处理的工作量是一样的。所以对DrawCall的优化,主要就是为了尽量解放CPU在调用图形接口上的开销。所以针对drawcall我们主要的思路就是每个物体尽量减少渲染次数,多个物体最好一起渲染。
2. 优化方式
(1)Draw Call Batching
采用批处理方式,Unity在运行时可以将一些物体进行合并,从而用一个描绘调用来渲染他们。
- 静态批处理:物体不移动,并且拥有相同的材质,静态批处理就允许引擎对任意大小的几何物体进行批处理操作来降低描绘调用。例如:在一个3D场景中,有Cube、Capsule、Cylinder、Sphere这个4个GameObject,注意之间不要有遮挡,另外还有Camera和Direction Light,它的处理前后的统计数据如下:



- 动态批处理
在这里使用时,遇到了坑,很多资料都没有提及到,在默认情况下,Unity是没有打开的,需要在Player Settings中进行设置的:

用了一个不错的例子来看,
for(int i = ; i < ; i++)
{
GameObject cube;
cube = GameObject.Instantiate(prefab) as GameObject;
}
动态批处理的结果是非常明显的(塔防游戏中估计能提高不少效率)

DrawCall的动态批处理存在着很多约束,所以默认是关闭的
a. 需要在每个顶点上进行一定的开销,所以动态批处理仅支持小于900顶点的网格物体;
b.着色器使用顶点位置,法线和UV值三种属性,那么你只能批处理300顶点以下的物体;如果你的着色器需要使用顶点位置,法线,UV0,UV1和切向量,那你只能批处理180顶点以下的物体(这个地方不懂);
c.不要使用缩放。分别拥有缩放大小(1,1,1) 和(2,2,2)的两个物体将不会进行批处理
d.统一缩放的物体不会与非统一缩放的物体进行批处理
e.用缩放尺度(1,1,1) 和 (1,2,1)的两个物体将不会进行批处理,但是使用缩放尺度(1,2,1) 和(1,3,1)的两个物体将可以进行批处理
f.使用不同材质的实例化物体(instance)将会导致批处理失败;
g.拥有lightmap的物体含有额外(隐藏)的材质属性,比如:lightmap的偏移和缩放系数等。所以,拥有lightmap的物体将不会进行批处理(除非他们指向lightmap的同一部分)。(什么是lightmap)
h.多通道的shader会妨碍批处理操作。比如,几乎unity中所有的着色器在前向渲染中都支持多个光源,并为它们有效地开辟多个通道。
i. 预设体的实例会自动地使用相同的网格模型和材质。
3. 打包图集
每个材质/纹理的渲染一定是会产生DrawCall的,这个DrawCall只能通过打包图集来进行优化,例如在2D游戏中使用了2张图片,它的数据为:

在Unity中,Window->2D->Sprite Packer,先转到Editor Settins中进行设置:

这次的结果,明显减少了一次Draw Batch:

Unity性能优化-DrawCall的更多相关文章
- Unity 性能优化(力荐)
开始之前先分享几款性能优化的插件: 1.SimpleLOD : 除了同样拥有Mesh Baker所具有的Mesh合并.Atlas烘焙等功能,它还能提供Mesh的简化,并对动态蒙皮网格进行了很好的支持. ...
- Unity性能优化(3)-官方教程Optimizing garbage collection in Unity games翻译
本文是Unity官方教程,性能优化系列的第三篇<Optimizing garbage collection in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...
- Unity性能优化(4)-官方教程Optimizing graphics rendering in Unity games翻译
本文是Unity官方教程,性能优化系列的第四篇<Optimizing graphics rendering in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...
- Unity性能优化(2)-官方教程Diagnosing performance problems using the Profiler window翻译
本文是Unity官方教程,性能优化系列的第二篇<Diagnosing performance problems using the Profiler window>的简单翻译. 相关文章: ...
- Unity性能优化(1)-官方教程The Profiler window翻译
本文是Unity官方教程,性能优化系列的第一篇<The Profiler window>的简单翻译. 相关文章: Unity性能优化(1)-官方教程The Profiler window翻 ...
- Unity性能优化的N种武器
贴图: l 控制贴图大小,尽量不要超过 1024 x1024: l 尽量使用2的n次幂大小的贴图,否则GfxDriver里会有2份贴图: l 尽量使用压缩格式减小贴图大小: l 若干种贴图合并 ...
- Unity性能优化专题---腾讯牛人分享经验
这里从三个纬度来分享下内存的优化经验:代码层面.贴图层面.框架设计层面. 一.代码层面. 1.foreach. Mono下的foreach使用需谨慎.频繁调用容易触及堆上限,导致GC过早触发,出现卡顿 ...
- Unity性能优化之特效合并
特效合并,意思是说将粒子所用的零碎图片,以shader为单位合并成一张图集,好处就是可以降低draw call.试想,合并前每个粒子使用一个material,而每一个material就要占用一个dra ...
- Unity性能优化-音频设置
没想到Unity的音频会成为内存杀手,在实际的商业项目中,音频的优化必不可少. 1. Unity支持许多不同的音频格式,但最终它将它们全部转换为首选格式.音频压缩格式有PCM.ADPCM.Vorbis ...
随机推荐
- LuaJIT 之 FFI
1. FFI 教程 原文: FFI Tutorial 相关链接:OpenResty 最佳实践之 FFI 加载 FFI 库 FFI 库时默认编译进 LuaJIT 中的,但是不会默认加载或初始化.因此,当 ...
- Flutter移动电商实战 --(46)详细页_自定义TabBar Widget
主要实现详情和评论的tab provide定义变量 自己做一个tab然后用provide去控制 定义两个变量来判断是左侧选中了还是右侧选中了.并定义一个方法来接受参数,修改是左侧还是右侧选中的状态值 ...
- WindowsForm客户端自动更新逻辑
启动客户端的时候,单独开一个线程,该线程主要是判断指定服务器上的更新包和本地使用的客户端是否一致,是否需要更新,不需要更新,则退出,需要更新则从服务端的下载更新包,然后提示用户是否更新,点击更新,启动 ...
- 如何实现 Https拦截进行 非常规“抓包” 珍惜Any 看雪学院 今天 前段时间在自己做开发的时候发现一个很好用的工具,OKHttp的拦截器(何为拦截器?就是在每次发送网络请求的时候都会走的一个回调)大概效果如下:
如何实现 Https拦截进行 非常规“抓包” 珍惜Any 看雪学院 今天 前段时间在自己做开发的时候发现一个很好用的工具,OKHttp的拦截器(何为拦截器?就是在每次发送网络请求的时候都会走的一个回调 ...
- python __iter__ 迭代器
1. 迭代器是什么? 迭代器是一个对象,是python非常强大的特性 根本上说, 迭代器就是有一个 next() 方法的对象, 而不是通过索引来计数. 当你或是一个循环机制(例如 for 语句)需要下 ...
- 打印变量地址-0x%08x
地址是8个16进制数. 1.8个16进制数:相当于32个二进制数.4G内存刚好可以用32位的二进制表示出来.2.因为变量或函数等等在运行时都是存储在内存中的,所以你用取地址符当然是取出计算机内存中的地 ...
- 004-nginx简介、安装配置【源码安装和mac安装】、基本使用
一.概述 1.1.Nginx是什么 Nginx是一款轻量级的Web服务器,也是一款轻量级的反向代理服务器[常用]. 1.2.Nginx能干什么 Nginx能干的事情很多,这里简要罗列一些: 1:直接支 ...
- rf笔记
1.使用robot 用例绝对路径 可执行用例 2.robot --h 可以查看命令用法 3. 创建字典 *** Settings *** Library Collections *** ...
- delphi两个取字串长度的函数strlen,length
━━━━━━━━━━━━━━━━━━━━━━━━━━ [strlen]PChar 串专用函数:串长度 procedure TForm1.BitBtn1Click(Sender: TObject); v ...
- C# Newtonsoft.Json JObject 操作
C# Newtonsoft.Json JObject 操作举例 JArray j = new JArray(); JObject obj = new JObject( ") ); JObje ...