大家好,最近项目需要用到后期效果,但是3.x目前还没有提供后期效果管线Flow
,所以抽时间自己定制了一个后期组件,在此与大家分享。
(注意,目前的源码是基于3.2.1,有同学反馈说3.3会报没有
ShaderPool
的错误,经测试,3.3已经没有renderer.ShaderPool
了;将这所有ShaderPool
的报错代码直接改为pass.getShaderVariant()
即可,其它无变化。
什么是后期?
后期也就是游戏界面输出到最后阶段,对最终的输出画面进行一系列的处理。
在此阶段界面已经是2D内容,不过其实如果你有3D世界的其它信息如深度信息,那么在此阶段也能处理一些3D的计算。这是个很深的话题,不在此帖讨论范围内。
后期有什么效果
bloom发光
模糊
径向模糊
风格化
等等
更多可参阅这篇文章
目前与大家分享的组件,实现了管线后期渲染流PostEffectFlow,及两个Stage
-
BloomStage
(泛光) -
VignetteStage
(黑边)
1,BloomStage
这个后期是我写这个组件的目的,也就是全屏泛光效果,先看下效果
(里面的绿点是录GIF的问题,和效果无关)
目前bloom的模糊pass是使用的Dual Blur,所以性能是所有模糊中最好的,另外为了性能我折中了一下效果,将模糊pass降低至了2个,如果需要更大的模糊范围及质量,可以自行修改代码中的BloomStage中的iteration值。(但我没有具体测试过占用的GPU时间,有兴趣的同鞋可以测试一下,最好分享一下结果,感谢!)
关于Dual Blur及性能对比,可以参阅 高品质后处理:十种图像模糊算法的总结与实现 - 知乎 这篇文章,这里直接帖上对比结果:
2,VignetteStage
这个效果也就是可以看见的图里的边缘的黑边,主要是我为了将它作为一个示例来写的,毕竟两个后期肯定满足不了大家的胃口,那么如果需要扩展自己的后期,参照这个来写就可以了,不难,写好后,在PostEffectComponent内添加即可。
3,关于DrawCall
-
BloomStage
因为有很多步骤,所以占用了5个DrawCall,但是由于子pass都被降了一半的分辨率,并且由于Dual Blur
的pass间降尺寸的特性,所以基本上中间的子pass几乎不会占用GPU时间,所以大体总的算来,大概是3个DrawCall左右所占用的时间。
这里顺便解释一下,并不是DrawCall越多越慢,而是要看这个drawcall具体做了什么事,如果你一个drawcall,FBO尺寸是1x1,并且渲染shader里只直接输出了一个颜色。那么像这种drawcall你在一帧调一万次估计都不见得会卡。不过总的,性能的调节及取舍,需要自己来根据自己的项目调节哈。 -
VignetteStage占1 DrawCall
4,源码类说明及使用方法
-
类说明(简单说明,具体的自己看源码吧)
-
PostEffectComponent
主组件类 -
post-effect-flow
管线扩展Flow -
post-stages/bloom-effect.ts / .effect
BloomStage渲染逻辑及shader -
post-stages/vignette-stage.ts / .effect
VignetteStage渲染逻辑及shader -
IEffectStage.ts
后期Stage需要实现的接口
-
-
工作原理
post-effect-flow
渲染流是使用摄像机的输出来作为输入的,所以,使用时你必须将它挂到一个带有Camera
组件的node
上,在这里说个小插曲,一开始写完所有Flow
和Stage
后,发现Flow
和Stage
无法绑定Camera
和EffectAsset
资源,导致一度以为是IDE的BUG,纯代码测试都跑通了,就是卡在这步不知道要怎么办,后来转念一想,管线是引擎启动最开始就会创建的,它是不太可能会去加载额外的资源再来创建的,而且还是用户的自定义资源,所以后来就改为封装了一个Component
,这样就可以自己把这个组件拖到任意摄像机上了。 -
特性
- 因为是依赖摄像机的输出的,所以和具体使用什么管线无关。
- flow内的后期stages顺序无关(bloom除外,bloom会被强制放到第一渲染位)。
- 可实时调整各个stage的属性及启用禁用。
-
使用方法
- 添加
PostEffectComponent
至某个带有摄像机组件的node
。 - 将
bloom-effect.effect
及vignette-effect.effect
拖至对应的槽中。 - 调节参数即可。
- 注意,由于后期效果是针对Camera的,所以如果你的游戏内容和UI内容在同一个摄像机,那么UI也会被后期掉,所以建议使用Cocos的摄像机分屏功能,将游戏内容及UI内容分为两个摄像机,然后只为游戏内容的摄像机添加后期效果即可。
- 添加
5,缺点
- 无法预览,因为这是管线的渲染流程,组件在编辑状态时并不会执行逻辑代码,所以渲染flow在编辑状态时并没有被加入到当前IDE的渲染管线内,所以效果就不会显示。
- 目前
PostEffectComponent.ts
这个组件代码可以优化,比如改成后期stage数组,目前我懒我直接判断的if (bloom && vignette) { work }
,这种方式,但是事实上,post-effect-flow
是支持动态添加删除的,看各位童鞋自己优化吧
点击下载,并点赞~
assets.zip (11.7 KB)
MIT License
后记:
在这整个扩展过程中,学到了cocos的很多东西,3.x的架构特别是gfx的抽象真的是太赞了,虽然接触cocos还没有很长时间,但确实已爱上,并且希望cocos越来越好!