模糊有很多种,这里说高斯模糊,高斯模糊会给人一种毛玻璃的感觉.
以上三图分别为原图,高斯半径为1.5,高斯半径4.5
高斯模糊怎么模糊呢?
主要取决于一个函数:高斯函数,或者正态分布;
对于一个点,要对他进行模糊,就要选取周围的点的颜色值,然后将周围的点按权值相加,就得到了模糊后的点的颜色,
而这个权值,就是按照高斯函数来选取
下面的是一个高斯函数在(-1,-1)(-1,0).....这些点上的值
0.0453 |
0.0566 |
0.0453 |
0.0566 |
0.0707 |
0.0566 |
0.0453 |
0.0566 |
0.0453 |
这里,他的总和不是1,需要将每个位置的值除以总和,
得到下面的权重矩阵
0.0947 |
0.1183 |
0.0947 |
0.1183 |
0.1477 |
0.1183 |
0.0947 |
0.1183 |
0.0947 |
我们可以用js算出权重矩阵,然后传到着色器中
在片元着色器里,设置uniform float u_gaussRect[1020];
用来接收权重矩阵,然后接受数组大小.
权重矩阵怎么保存在数组里呢
我是保存为以下格式
[x偏移,y偏移,权重,x偏移,y偏移,权重,x偏移,y偏移,权重,.....]
比如上面的矩阵
[-1,-1,0.0947,-1,0,0.1183,.....]
for(int i=0;i<1020;i++){
if(i<u_gaussnum){
total+=texture2D(u_Sampler,
vec2(v_TexCoord.x+u_gaussrect[i*3]*dv,v_TexCoord.y+u_gaussrect[i*3+1]*dv))*u_gaussrect[i*3+2];
}
}
数组定义了1020个,我们还需要使用u_gaussnum来保证循环次数少于矩阵的大小
为什么不是在for循环中的条件判断,因为GL不能这样做,光栅化的时候,循环是需要被进行内联展开(网上没搜到多少说明,我想的是估计像光栅化一样的吧)的,这样就必须确保循环的次数是一定的,
这里使用取色器选取的位置还需要×一定的dv,dv是偏移,如果没有偏移,选区的周围的点就会离中心点太近,产生不了效果
代码没有帖,有需要的评论哦