几乎连续的双Kawase模糊
2023年6月3日修订 发现还是在降采样升采样后进行线性插值来获取中间程度的模糊效果比较好,所以后面的代码也都改过来了,不过理论上的部分倒是没必要改。顺便也花了点时间写了一个Shadertoy作为演示: Dual Kawase Blur 写这篇文章的原因 网上已经有了很多很多的双Kawase模糊的现成的案例,但是存在以下几个问题:1. 绝大部分的文章都只给了代码,没有相应的解释,至多会给一张直接从Arm的pdf截取的图示,而这张图示画了一堆方框和符号,却没有说明这些图案代表的含义。2. 绝大部分的文章通过修改采样的距离来控制模糊的程度,这个的缺点我们后续再谈。3. 绝大部分的文章并没有考虑模糊程度从0开始逐渐增大的动态过程,使用降采样和升采样往往会破坏整个画面的连续性。 如果只是想要获得一个模糊的画面,只需要做几次降采样和升采样就能完成了,但我希望能有一个连续地逐渐地变模糊的过程,因此我开始了量化双Kawase模糊的想法。 双Kawase模糊(Dual Kawase Blur) 双Kawase模糊是2015年Arm在Kawase模糊的基础上提出的一种通过降采样和升采样来快速且高效地进行高质量大半径模糊的一种方法,具体的pdf可以从这里找到。 这里是一张双Kawase模糊的图示,表示了双Kawase模糊在降采样和升采样时的操作。细的黑线对应的格子是原始的像素(或是升采样后的像素),粗的黑线对应的格子是降采样后的像素。叉对应的是当前模糊的像素,圆对应的是当前模糊的像素所需要采样点。粉色对应的是降采样时的模糊的像素和采样点,绿色对应的是升采样时的模糊的像素和采样点。 从这张图中也可以看到双Kawase模糊利用双线性采样来节省采样数的操作。在降采样时实际采样了当前像素周围一共十六个像素的颜色;在升采样时实际采样了当前像素周围一共十三个像素的颜色。而如果在做降采样时,对于奇数个像素除以二向下取整,或者是在降采样时使用了不恰当的偏移(比如1.5倍的偏移),会导致降采样的采样点落在原始像素的中心,这时即使使用了双线性采样,也只等价于采样一个像素。 因此为了让每一个像素都能对模糊做到应用的贡献,为了达到比较好的模糊效果,我们这里限制双Kawase模糊的采样偏移为一倍(也就是严格按照采样点进行最优的双线性采样)。而通过多次降采样和升采样达到合适的模糊半径。 量化双Kawase模糊 降采样和升采样有一个缺点,就是只要发生了降采样和升采样,就必然会带来模糊。这时有两种方法,一种是在原始分辨率下通过消耗更大的方式进行加权模糊来逼近双Kawase模糊配合降采样带来的模糊;另一种是在零次和一次双Kawase之间线性插值得到一张介于两者之间模糊程度的图像。综合两者来看,线性插值得到的效果更为平滑,效果上稍“错误”一些,但完全在可接受的范围内。 我这边写了一个小小的脚本,去计算原始分辨率下值为1的像素点,在经过一次双Kawase模糊后,其他像素的值。通过多项式拟合这些模糊后的值,就能利用这些值来逼近双Kawase模糊的效果了。我这边对8x8的像素做了计算(实际上模糊的核心应该更大一些,不过我懒得改之前的代码了)。计算出的权重如下: 0.0003255208 0.001464844 0.003092448 0.004231771 0.004231771 0.003092448 0.001464844 0.0003255208 0.001464844 0.004882813 0.009440104 0.01204427 0.01074219 0.007486979 0.004231771 0.001464844 0.004394531 0.01334635 0.02311198 0.02701823 0.0218099 0.01334635 0.007486979 0.003092448 0.01009115 0.02571615 0.03808594 0.04329427 0.03678386 0.0218099 0.01074219 0.004231771 0.01529948 0.03222656 0.04069011 0.04589844 0.04329427 0.02701823 0.01204427 0.004231771 0.01416016 0.0296224 0.03678386 0.04069011 0.03808594 0.02311198 0.009440104 0.003092448 0.007324219 0....