原文地址:http://blog.csdn.net/yanchezuo/article/details/77337755
4年前遇到的花屏问题,如今又遇到了。这次通过不断的测试、重现、修改、反思,终于得出了最终原因和最终答案!
- 你的界面花屏了?
去检查一下,你游戏中的相机clearFlag的设置,是不是没有clearFlag设置为SolidColor或者SkyBox的相机?
解决方案:
一定要有一个clearFlag设置为SolidColor或者SkyBox的相机,并且这个相机的depth为你所有相机中depth的最小值(保证这相机先渲染)
- 原理
Unity每个渲染帧的开始,并不会清空颜色缓冲区和深度缓冲区,是通过设置相机的clearFlag来起作用的,具体如下:
ClearFlag | 颜色缓冲区 | 深度缓冲区 |
---|---|---|
SkyBox | 改变,设置为skyBox的颜色 | 不改变 |
SolidColor | 改变,设置为BackGround颜色 | 不改变 |
DepthOnly | 不改变 | 改变,清空深度缓冲 |
因此,如果场景中没有一个改变颜色缓冲区的相机,在渲染的初始帧,颜色缓冲区会保留上一帧的结果。
在此,给一种出现花屏的现象的实例:
场景中有两个相机,设置分别为:
相机 | clearFlag | depth | Culling Mask |
---|---|---|---|
gameCam | depthOnly | -1 | GameScene |
uiCame | depthOnly | 1 | UI |
渲染顺序为:
颜色缓冲上一帧残留(A) -> 当前渲染帧开始 -> gameCame 渲染,修改颜色缓冲区 (B)-> uiCam渲染,修改颜色缓冲(C) -> 显示到屏幕上.
最终渲染的是A+B+C
拓展:花屏和卡帧
当然,如果在切换界面的时候,不卡帧,其实也不会出现花屏的现象。这一条先占上坑,改天详细说明。
拓展:花屏和多线程渲染
在我的测试中,如果开启了多线程渲染,一卡帧,很容易就出现花屏。相反,不开启多线程渲染,基本上是不会有花屏现象的。特别是开了垂直同步之后,cpu会等待gup渲染结束再进行下一帧的计算。
ps.Unity3d垂直同步有个坑,和帧率相关
垂直同步QualitySettings.vSyncCount的设置,值可以为0,1,2。
vSyncCount | 是否等待GPU渲染完成 | 游戏帧率 |
---|---|---|
0 | 否 | 不影响帧率设置 |
1 | 是,一个缓冲buffer | 影响,强制60fps |
2 | 是,2个缓冲buffer | 影响,强制30fps |
- 拓展:花屏和GL.Clear()
GL.Clear()当然是可以清除颜色缓冲的。不过,由于不知道卡几帧,每帧都设置GL.Clear()也是挺奇怪的。
所以,在切换界面的时候调用一次GL.Clear()不能完全解决花屏的问题。
GL.Clear()是使用,参见:
http://blog.csdn.net/yanchezuo/article/details/12751917