关于Unity 5.x 新功能 CommandBuff 的无力吐槽

今天冒着严重的花粉过敏+浑身浮肿,还是把Env Distortion 这个游戏内效果重新实现了一遍。
之前为方便快速出效果,我使用 ShaderLab的内置功能 Grab Pass将效果实现。
关于Unity 5.x 新功能 CommandBuff 的无力吐槽_第1张图片

效果很完美,半透明被很好地被采集并被扭曲。但是通过OpenGL 2.0实机测试,发现只要这东西一出现,帧数秒降20帧,再次让游戏成功探底。虽然我听说过这东西很消耗,但我却猜不到结局是这么惨烈。
好在这些尽在我掌控之中!我原本也要重写这一块,当我得知效率损失严重时,甚至我还有点儿小兴奋——“我会拯救你们的!”
经过思考我定下A,B两套方案。
先说B方案比较常规,新建一个摄像机专门画背景然后拿这张RT去Shader里面随便搞。但这种做法总觉得不够优雅,于是我想到了那个让我向往已久的功能——传说中的CommandBuff.
好,下面我们着重来说说A方案。A方案的整体思路是,创建一个CommandBuff,封装这一套:截图,渲图,传图的流程,然后把这张图传给Shader就OK。听起来简直无懈可击!
可是结果却出乎意料,当我把一切做好, 屏幕上出现这个诡异的情况。
关于Unity 5.x 新功能 CommandBuff 的无力吐槽_第2张图片
粒子和场景的扭曲图片出现了残影,经过痛苦的分析终于确定了原因,这是因为Camera没有剔除这个有Distortion效果的Plane,在渲染RT的时候,把原始Plane也画上去了,所以原始Plane上的颜色不断累积,造成拖尾残影。
查阅了很多资料,能解决这个问题的方法就是指定这个Plane的渲染开关,也就是CommandBuff.DrawMesh() 这个功能,强制Mesh渲染与否,听起来好像很美好,但结果却大跌眼镜。
如果这个Plane和场景之间有遮挡关系,那么除非我把这个Plane以及在这个Plane与摄像机之间的所有遮挡Mesh都用DrawMesh()控制,不然遮挡就会出现问题,Plane永远画在你所指定的CameraEvent时间点,如果CameraEvent为AfterEverything,那很抱歉,这个Plane永远最后画(从FrameDebuger可以清晰地看到)。
关于Unity 5.x 新功能 CommandBuff 的无力吐槽_第3张图片
冥思苦想,解决方案又回到了CullingMask上,也就是说,我需要一个摄像机,专门画除了Plane之外的所有东西,这就回到了A方案上。
但CommandBuff可以拿到一张Temp RT实在是太方便太诱人了,所以我决定把A方案和B方案结合了一下,用CommandBuff在这个新摄像机上完成过去在Main Camera上一系列工作。

走了一圈,最后几乎回到原点。总结下来,CommandBuff的使用时机是关键,CameraEvent完全影响哪些能画到RT上哪些画不上;同时因为缺乏CullingMask这样强大的功能,这导致CommandBuff除了能做一些全屏效果外,几乎没有什么用处。
所以应对复杂场景剔除渲染,还是老老实实回到创建摄像机这个老路上,如果做一些全局效果,可以用CommandBuff顶上,现在看,这是最合适的用法了。

你可能感兴趣的:(Unity3d,Effect,unity,opengl,Grab-Pass,CommandBuf)