大家好,又见面了,我是你们的朋友全栈君。
前言
游戏开发圈里的人一定听过优化游戏要降低DrawCall,这样到底什么是DrawCall呢?Unity中应该如何降低DrawCall,这里就来讲解一下关于DrawCall知识点。
1.是谁拖了后腿?
通俗的来说就是Cpu:(#`O′)喂你好,是Gpu吗?快点醒醒我这里又有画画的任务了(Cpu调用Gpu的次数),打一个比方比如上传很多文件到百度云或其他地方时,都会把它压缩到一个文件夹里,不会把它们分开上传(当然还有原因就是它们数据是相关,比如是主题的一套ico文件或软件的安装文件),排除这些和文件整合的原因,假设网速没有波动,分开传和压缩包,压缩包速度一定快很多的(不仅仅是因为压缩包更小),主要是每次上传还有一些预备动作(比如与服务器链接,初始化Socket等等),细心的会发现文件当拖动到百度云会有几毫秒的延迟。其实优化DrawCall主要是Cpu的处理速度的优化,Cpu和Gpu是并行工作的,处理的方式有一个命令缓存区,具体如图所示:
别看图中画的好像是Cpu在等待Gpu,实际上Cpu才是拖后腿的那个,现实中Gpu早就把命令缓存区里命令都处理完毕了,Cpu确还在准备DrawCall的命令,Cpu通过图像编程接口向命令缓存区添加命令,而Gpu通过缓存区获取命令处理。
2.为什么会拖后腿?
在每次调用DrawCall之前,因为Cpu需要向Gpu发送很多内容,包括数据、状态和命令,在这个阶段Cpu需要完成很多工作,比如检查渲染状态等(有一堆工作要Cpu处理,才会存放到缓存区),存放到缓存区以后,Gpu就要开始工作了,Gpu渲染能力还是很强的,渲染200或2000个三角网格通常看不出区别,导致Gpu渲染速度大于Cpu的提交速度,影响渲染流水线速度就是提交比较慢的Cpu(现在知道玩游戏要买的电脑配置了吧,一般选择Cpu比较好的,Gpu一般的即可,当然游戏画面特别好的,还是建议把显卡买好点的,有些游戏硬性条件普通显卡根本渲染不了,并不是渲染速度的问题了),最后可想而知Cpu会花费大量的时间在提交DrawCall的路上,造成Cpu的过载,Gpu确会出现空闲。
3.优化DrawCall
降低DrawCall的方式还是很多的,先讨论如何降低2d游戏的DrawCall,2d游戏的资源都是图片,单个图片调用一次DrawCall会导致Cpu太难了,这样有没有办法降低提交次数呢?可以通过打包图集的操作来降低DrawCall,比如界面所用到的图片打包成图集或者人物的序列图打包到图集,具体如图所示:
可能会思考把所有界面的资源打包到一个图集里,岂不是美哉?这个时候Gpu会说太难了,只是渲染某个界面却要拿出整个图集去操作,热更新也会说我太难了,只是更新某个界面里的按钮图片样式却要替换整个图集,所以合理打包图集。 其实对图集这个东西理解还是比较深刻,写过和看过图集打包软件的源代码(当然和Unity的图集不是一个,但是大同小异),一般情况就是把图片数据全部写到一个文件里,然后保存ID或其他信息可以把单个图片找出来的方式,通过图集实现了提交大量的DrawCall。接下来思考模型如何降低DrawCall的调用。 Unity中可以通过静态批处理实现优化DrawCall,静态批处理的原理就是合并网格,而合并过程是需要消耗时间,因此批处理技术更加适合那些静态的物体,比如不会动的地面、树和石头,对于这些静态物体我们合并一次即可,当然可以使用动态批处理,但是,由于这些物体不断移动的,因此每帧都需要进行合并发送给Gpu,对时间和空间都有一定的影响。具体如图所示:
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/125371.html原文链接:https://javaforall.cn