有一个东西已经杀死了上千个移动端游戏的GPU性能,那就是Unity OverDraw,因此不要让overdraw毁灭你的游戏;
本文的大概内容
学习什么是overdraw,以及它是如何影响游戏的GPU性能的
三个技术用于衡量游戏中的overdraw(我们相信:No measure,No Improve!)
学习减少Unity OverDraw的策略
最简单最快速的方式是使用Unity内置的overdraw,在场景窗口中我们可以通过设置Overdraw mode来看到一个热图效果,通常颜色最深的地方代表问题最严重;
不过需要注意:它显示的效果是错误的,是具有误导性的,因为它的绘图原理是错误的;
Unity仅仅是使用一个额外的没有z-writing的shader来绘制它,它并没有考虑到渲染管线中做的各种剔除优化等,比如不透明物体从前往后渲染等;
针对这一点还可以参考:
但是这种方式还是有用的,另外;
在Unity新推出的HDRP中已经提供了一个更好的Overdraw调试,它的效果更好更准确;
RenderDoc是一个非常著名的GPU开源调试工具,关于它的一些使用教程等后面会给出链接,不熟悉的同学可以了解一下;
3.使用Compute Shaders测量Overdraw
这是一种更具体的方式;
现在你已经能够从Overdraw方面了解你的游戏在做什么,那么问题来了:你怎么解决这个问题?
同时,还有另一个重要的问题:如何预防overdraw?
在本节我们将给出一些建议
与流行的游戏开发理念相反,不透明物体的渲染可能引发大量的overdraw;
不透明物体的overdraw比透明物体的overdraw消耗要低,因为不透明物体的绘制是做像素的替换,而透明物体则需要做alpha混合,在移动端这个操作是更费的;
不要低估不透明物体的overdraw导致的性能消耗,因为大量浪费内存带宽的代价是远高于透明物体的混合代价的(overdraw导致的额外的像素写入并不是没有代价的,纹理采样,写入FB都是需要占用内存带宽的);
Unity尽可能从前向后渲染不透明物体,距离相机更近的物体被渲染,距离相机更远的会在深度测试中被丢弃,这种方式是基于每个对象的包围盒中心到相机的距离进行排序;这种方式是有利于GPU的,但是有一些情景会打破这种排序方式并增加overdraw;
低效的几何体导致的Overdraw;
unity合批导致的Overdraw;
还要了解不透明物体的渲染顺序:
可能最差类型的Overdraw就是来源于半透明物体;
因为半透明的渲染通常伴随着alpha的混合,需要额外的数学计算以及读写操作;而且半透明渲染不做深度写入,所以不能有像素的丢弃,可能需要写入更多的像素;
所以我们必须要减少透明像素的绘制数量以及它们的消耗;
减少渲染的透明层级数量;
减少透明几何体占用的屏幕尺寸
可以减少透明物体的scale大小
尽量从贴图中移除100%透明的像素(比如一张纹理很大,但是大多数区域的alpha值都是全透明的)
使用一个轻量的网格来减少全透区域
Unity UI通常是Overdraw最严重的地方,因为系统只支持用整个Quad来进行渲染,因此它很容易导致在Quad的边缘处进行多余的绘制
一个高级的技术是可以尝试使用透明的方式来绘制部分UI,在geometry队列之前(因为场景中的不透明物体都需要在Geometry进行绘制);
(UWA2020Day中讲到Overdraw优化的时候也给出了)
UI开发与优化知识Tree:https://blog.uwa4d.com/archives/UWA_UITree.html
UWA技术直播视频集锦(NGUI、UGUI的优化,包括Drawcall、Overdraw等): https://blog.uwa4d.com/archives/video_UI.html
后处理方面
尽可能避免全屏后处理,全屏后处理会导致严重的overdraw,应该在移动平台上尽量避免;
注意:如果不能再减少overdraw,那么我们可以通过修改混合模式,在移动平台上使用Additive Blending代替alpha blending会消耗更少。
https://renderdoc.org/builds
https://docs.unity3d.com/Manual/RenderDocIntegration.html
帧分析和调试工具
https://zhuanlan.zhihu.com/p/80704313
https://zhuanlan.zhihu.com/p/74622572
https://forum.unity.com/threads/sceneview-overdraw-mode-is-misleading.545748/