模糊算法
大部分模糊算法参考在这里
均值模糊
原理:通过卷积核对周围的像素进行平均,所有权重都是一样的
shader1 2 3
| // 这个是内置变量,x = 1/width, y = 1/height, z = width, w = height // 这样x,y就能代表偏移值 float4 _MainTex_TexelSize;
|
2 * 2均值模糊,其他模糊以此类推
shader1 2 3 4 5 6 7 8
| // 2*2 均值模糊 half4 d = _MainTex_TexelSize.xyxy * half4(-1,-1,1,1) * _BlurOffset; half4 s= 0; s += tex2D(_MainTex, i.uv + d.zw); s += tex2D(_MainTex, i.uv + d.zx); s += tex2D(_MainTex, i.uv + d.xz); s += tex2D(_MainTex, i.uv + d.xy); s *= 0.25;
|
可通过在C#脚本中可以提高迭代次数
1 2 3 4 5 6 7 8
| Graphics.Blit(source, rt1, material);
for(int i =0;i<_Interation;i++){ Graphics.Blit(rt1,rt2,material); Graphics.Blit(rt2,rt1,material); } Graphics.Blit(rt1, destination, material);
|
高斯模糊
原理:同均值模糊,但是权重从中心往边缘呈高斯分布
优化后的高斯模糊 —> 直接使用55高斯核会很浪费,转换成两次1\5的操作,一次横向,一次纵向
因为已经有权重所以不用最后再除了
shader1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 水平方向 half4 frag_HorizontalBlur (v2f_img i) : SV_Target{ half4 d = _BlurOffset.xyxy * half4(-1,-1,1,1); half2 uv1 = i.uv + _BlurOffset*half2(1,0)*-2.0; half2 uv2 = i.uv + _BlurOffset*half2(1,0)*-1.0; half2 uv3 = i.uv; half2 uv4 = i.uv + _BlurOffset*half2(1,0); half2 uv5 = i.uv + _BlurOffset*half2(1,0)*2.0;
half4 s= 0; s += tex2D(_MainTex, uv1) * 0.05; s += tex2D(_MainTex, uv2) * 0.25; s += tex2D(_MainTex, uv3) * 0.4; s += tex2D(_MainTex, uv4) * 0.25; s += tex2D(_MainTex, uv5) * 0.05; return s; }
|
双重模糊
先降采样,再升采样
shader层面不用修改
C#中在迭代过程中降低和增加图片大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| for(int i =0;i<_Interation;i++){ RenderTexture.ReleaseTemporary(rt2); width /= 2; height /= 2; rt2 = RenderTexture.GetTemporary(width,height); Graphics.Blit(rt1,rt2,material,0);
RenderTexture.ReleaseTemporary(rt1); width /= 2; height /= 2; rt1 = RenderTexture.GetTemporary(width,height); Graphics.Blit(rt2,rt1,material,1); }
for(int i =0;i<_Interation;i++){ RenderTexture.ReleaseTemporary(rt2); width *= 2; height *= 2; rt2 = RenderTexture.GetTemporary(width,height); Graphics.Blit(rt1,rt2,material,0);
RenderTexture.ReleaseTemporary(rt1); width *= 2; height *= 2; rt1 = RenderTexture.GetTemporary(width,height); Graphics.Blit(rt2,rt1,material,1); }
|