一、什么是DrawCall

DrawCall的含义就是CPU调用图像编程接口,以命令GPU进行渲染的操作。

CPU和GPU通过使用一个命令缓冲区实现并行工作。命令缓冲区包含一个命令队列,CPU向其中添加命令,GPU从中读取命令,添加和读取是相互独立的,因此使得CPU和GPU可以独立工作。命令缓冲区中的命令有很多种类,DrawCall就是其中一种。

二、为什么DrawCall多了会影响帧率

DrawCall中真正造成性能问题的元凶是CPU。

在每次调用DrawCall之前,CPU需要向GPU发送很多内容,包括数据、状态和命令等。在这一阶段,CPU需要完成很多工作,例如检查渲染状态等。而一旦CPU完成了这些准备工作,GPU就可以开始本次渲染。GPU的渲染能力很强,渲染速度往往快于CPU提交命令的速度。如果DrawCall的数量太多,CPU就会把大量时间花费在提交DrawCall上,造成CPU的过载。

三、DrawCall优化

优化有一下几个解决方案:

1、使用Draw Call Batching,也就是批处理。Unity在运行时可以将一些物体进行合并,从而用一个DrawCall来渲染他们。具体下面会介绍。

2、通过把纹理打包成图集来尽量减少材质的使用。

3、尽量少的使用反光,阴影之类的,因为那会使物体多次渲染。

Draw Call Batching技术

Unity内置了Draw Call Batching技术,它的主要目标就是在一次DrawCall中批量处理对个物体。只要物体的变换和材质相同,GPU就可以按完全相同的方式进行处理,即可以把它们放在一个Draw Call中。

Draw Call Batching技术存在缺陷,当它需要把一个Batch中的所有物体组合到一起,相当于创建了一个与这些物体加起来一样大的物体。这就需要分配相应大小的内存,也需要消耗CPU时间。特别是对于移动的物体,每一帧都得重新进行组合。但对于静止不动的物体,只需要进行一次组合。

Unity提供了Dynamic Batching和Static Batching两种方式。

Dynamic Batching

Dynamic Batching是完全自动进行的,不需要也无法进行任何干预。

动态批处理的约束:

1、批处理动态物体需要在每个顶点上进行一定的开销,所以动态批处理仅支持小于900顶点的网格物体。

2、如果着色器使用顶点位置,法线和UV值三种属性,那么只能批处理300顶点以下的物体;如果着色器需要使用顶点位置,法线,UV0,UV1和切向量,那么只能批处理180顶点以下的物体。

3、不要使用缩放,分别拥有缩放大小(1,1,1)和(2,2,2)的两个物体将不会进行批处理。

4、统一缩放的物体不会和非统一缩放的物体进行批处理。

5、使用缩放尺度(1,1,1)和(1,2,1)的两个物体将不会进行批处理,但是使用缩放尺度(1,2,1)和(1,3,1)的两个物体将可以进行批处理。

6、使用不同材质的实例化物体将会导致批处理失败。

7、拥有lightmap的物体含有额外(隐藏)的材质属性,比如:lightmap的偏移和缩放系数等。所以,拥有lightmap的物体将不会进行批处理(除非他们指向lightmap的同一部分)。

8、多通道的shader会妨碍批处理操作。比如,几乎unity中所有的着色器在前向渲染中都支持多个光源,并为它们有效地开辟多个通道。

9、预设体的实例会自动地使用相同的网格模型和材质。

Static Batching

Static Batching需要把静止的物体标记为Static,然后无论大小,都会组成Batch。

如何对动态加载的静态物体进行静态合批操作:
    GameObject go = (GameObject)Instantiate(...);
    go.isStatic = true;//将实例化的物体设置为静态
    go.transform.parent = root.transform;
    gosList.Add(go);
    gos = gosList.ToArray(); 
    StaticBatchingUtility.Combine(gos, root);静态合并

高效利用Draw Call Batching

1. 首先是尽量减少场景中使用的材质数量,即尽量共享材质,对于仅纹理不同的材质可以把纹理组合到一张更大的纹理中。

2. 然后是把不会移动的物体标记为Static。此外还可以通过CombineChildren脚本(StandardAssets/Scripts/UnityScripts/

CombineChildren)手动把物体组合在一起,但这个脚本会影响可见性测试,因为组合在一起的物体始终会被看作一个物体,从而会增加GPU要处理的几何体数量,因此要小心使用。

3. 对于复杂的静态场景,还可以考虑自行设计遮挡剔除算法,减少可见的物体数量同时也可以减少Draw Call。

NVIDIA 在 GDC 曾提出,25K batchs/sec 会吃满 1GHz 的 CPU,100的使用率。所以他们推出了一条公式,来预估游戏中大概可以 Run 多少个 Batch:
     
    举个例子:如果你的目标是游戏跑30FPS、使用2GHz的CPU、20%的工作量拨给Draw Call来使用,那你每帧可以有多少Draw Call呢?
333 Batchs/Frame = 25K * 2 * (0.2/30)

参考资料:https://blog.csdn.net/zhongdong00/article/details/80590396

了解DrawCall的更多相关文章

  1. U3D DrawCall优化手记

    在最近,使用U3D开发的游戏核心部分功能即将完成,中间由于各种历史原因,导致项目存在比较大的问题,这些问题在最后,恐怕只能通过一次彻底的重构来解决 现在的游戏跑起来会有接近130-170个左右的Dra ...

  2. unity panel删除drawcall失败导致的残留影像

    ngui panel 被隐藏或者删除的时候调用ondisable,清空drawcall,如果这个操作是在ontriggerenter等物理操作中就会删除不掉导致留下残影 解决方式 : 讲这些操转移到协 ...

  3. Unity的DrawCall

    图形引擎渲染画面的过程 Unity(或者说基本所有图形引擎)生成一帧画面的处理过程大致可以这样简化描述: 1. 可见性测试 1. 引擎首先经过简单的可见性测试,确定摄像机可以看到的物体 2. 准备好物 ...

  4. DrawCall

    [精]draw call 理解和优化 http://bubuko.com/infodetail-387899.html DrawCall 优化 . http://www.cnblogs.com/sof ...

  5. NGUI之渲染DrawCall的合并

    在Unity中,每次引擎准备数据并通知GPU的过程称为一次Draw Call.Draw Call值越低,会得到更好的渲染性能. (NGUI 查看DrawCall工具(NGUI-OPEN-Draw Ca ...

  6. NGUI 减少drawcall规则

    前置说明一: Unity中的drawcall定义: 每次引擎准备数据并通知GPU的过程称为一次Draw Call. Unity(或者说基本所有图形引擎)生成一帧画面的处理过程大致可以这样简化描述:引擎 ...

  7. Unity优化之减少Drawcall

    简单来说,Drawcall就是屏幕渲染一次所需要的开销,为了较少消耗,提高性能,一般有以下几种方法. 一: 批处理 1.动态批处理 如果动态物体共用着相同的材质,那么Unity会自动对这些物体进行批处 ...

  8. 【转】 U3D DrawCall优化手记 - 夜阑卧听风吹雨

     原文  http://www.cnblogs.com/ybgame/p/3588795.html 在最近,使用U3D开发的游戏核心部分功能即将完成,中间由于各种历史原因,导致项目存在比较大的问题,这 ...

  9. 开发自定义ScriptableRenderPipeline,将DrawCall降低180倍

    0x00 前言 大家都知道,Unity在2018版本中正式推出了Scriptable Render Pipeline.我们既可以通过Package Manager下载使用Unity预先创建好的Ligh ...

  10. (转)最近一个项目中关于NGUI部分的总结(深度和drawCall)

    在自己最近的一个项目中,软件的界面部分使用了NGUI来进行制作.在制作过程中,遇到了一些问题,也获取了一些经验,总结下来,作为日后的积累. 1.NGUI图集的使用. 此次是第一个自己正儿八经的制作完整 ...

随机推荐

  1. VMware ESXi 和 VMware Server 有区别

    VMware ESXi 和 VMware Server 有区别: VMware ESXi 是一个企业级虚拟机管理程序,提供接近本机性能的祼机体系结构.各种旨在提高整合率的功能(例如取消内存复制),以及 ...

  2. element ui的表格列设置fixed后做动态表格出现表格错乱

    最近使用element-UI时,使用table做动态表格,当操作列使用fixed时,动态切换表格列设置设置时就会出现错乱,情况如下: 解决方法: 把el-table-column上的key设成一个随机 ...

  3. aarch-linux-gnu-g++ install

    # apt install g++-aarch64-linux-gnuReading package lists... 0% Reading package lists... Done Buildin ...

  4. ubuntu配置pip3以及scrapy

    .安装支持pip3 sudo apt-get install python3-pip .安装scrapy 首先需要安装scrapy依赖项,否则scrapy安装失败,执行如下命令: sudo apt-g ...

  5. Linux创建删除文件和文件夹

    要想删除和创建,需要有root权限 [xwg@bogon ~]$ su root密码:[root@bogon xwg]# cd /home/a      切换到目录a[root@bogon a]# t ...

  6. BOM:浏览器对象

    1.window是javascript的顶级对象        window有很多内置方法 如 alert open 自定义函数 2.window是bom的顶级对象,通常情况下,可以省略 window ...

  7. python并发——从线程池获取返回值

    并发是快速处理大量相似任务的绝佳办法,但对于有返回值的方法,需要一个容器专门来存储每个进程处理完的结果 from multiprocessing import Pool import time #返回 ...

  8. springboot 配置跨越访问

    import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.H ...

  9. LeetCode 10. 正则表达式匹配(Regular Expression Matching)

    题目描述 给定一个字符串 (s) 和一个字符模式 (p).实现支持 '.' 和 '*' 的正则表达式匹配. '.' 匹配任意单个字符. '*' 匹配零个或多个前面的元素. 匹配应该覆盖整个字符串 (s ...

  10. python操作s3 -- boto2.x

    以下是python操作s3常用方法: boto s3手册:http://boto.readthedocs.org/en/latest/ref/s3.html boto s3快速入门:http://bo ...