写在前面
好久没有写shader了,最近项目中需要实现一个弹窗背景是模糊的游戏场景。大致效果如下:

看起来好像比较抽象!?我去找个好看的效果图。


原理
首先我们看一下图层结构:

bg是我们的需要模糊的游戏页面,target和message box是我们需要显示先模糊上层的。blurBg是我们的模糊层。
我们想实现这个效果最简单的方法就是让美术出一个透明模糊图即可,把这个图放在我们的模糊层。就完事了。事实好像是这样要简单很多哈...

糟了,转不回来了,我们来说原理....
原理其实很简单,我们需要先把当前屏幕所渲染的画面记录下来,存到一个贴图里,然后对这个图片做模糊。
获取当前屏幕颜色并记录下来,我们使用的是:
GrabPass {}
我们只是需要在subshader中声名一个这个pass块即可。它默认会把当前屏幕渲染画面存在一个叫“_GrabTexture”的贴图中。当然我们也可以自定义名字:
GrabPass{"_BackgroundTexture"}
我们获得了这张图然后开始做模糊,模糊我们都知道是使用卷积。但是个人认为模糊就是把我们需要模糊的图,像是复制几张相同的图片,然后再把几张图片按照一定的偏移量来摆设。这样就出现了模糊的效果,如果我们把偏移值放大一些,我们就可以看到我们卷积生成的几张图。几乘几的卷积就是几张图。可以看看源码:
这里的模糊算法我使用的是《Unity shader入门精要》里屏幕后处理高斯模糊里的算法。这里有一个优化点,就是我们可以把计算卷积点放在片元函数中。
差不多就这么多了吧~
对了可以关注一下我的公众号哦~

网友评论