简介
KawaseBlur效果与高斯模糊相近,优化比高斯模糊更好,而DualKawaseBlur的性能优化比KawaseBlur更加强大
DualKawaseBlur采用了下方两种Kawase进行合成达到的模糊效果
效果
模糊强度为20情况下三种残影形状(从左到右:高斯模糊,Kawase模糊,双重Kawase模糊),因为这里运用的是Sprite,所以只能看出他们残影不用,实际运用到屏后处理,效果差距都相互接近。
源码
Shader "FoxShader/KawaseBlur"
{
Properties
{
//2D纹理
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" { }
//模糊强度
_BlurSize ("_BlurSize", Range(0, 20)) = 1.914
//渐淡
_SpriteFade ("SpriteFade", Range(0, 1)) = 1.0
}
SubShader
{
//渲染顺序=3000 忽略投影 渲染类型=半透明物体 预览类型=Plane 能否使用Sprite
Tags { "Queue" = "Transparent" "IgnoreProjector" = "true" "RenderType" = "Transparent" "PreviewType" = "Plane" "CanUseSpriteAtlas" = "True" }
//渲染设置
//深度写入 混合类型=传统透明度混合 遮挡剔除
ZWrite Off ZTest Always Blend SrcAlpha OneMinusSrcAlpha Cull Off
Pass
{
CGPROGRAM
//作为顶点着色器编译函数
#pragma vertex vert
//作为片元着色器编译函数
#pragma fragment frag
//使用低精度
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
//顶点数据结构
struct appdata_t
{
float4 vertex: POSITION;//顶点位置
float4 color: COLOR;//颜色
float2 texcoord: TEXCOORD0;//UV坐标
};
//片元数据结构
struct v2f
{
float2 texcoord: TEXCOORD0;
float4 vertex: SV_POSITION;//固定值——顶点位置
float4 color: COLOR;
};
sampler2D _MainTex;
float4 _MainTex_TexelSize;//计算相邻像素的纹理坐标偏移量
float _SpriteFade;
float _BlurSize;
//顶点着色器代码块
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);//对象空间转裁剪空间
OUT.texcoord = IN.texcoord;
OUT.color = IN.color;
return OUT;
}
//核心算法
half4 KawaseBlur(sampler2D tex, float2 uv, float2 texelSize, half pixelOffset)
{
half4 o = 0;
o += tex2D(tex, uv + float2(pixelOffset +0.5, pixelOffset +0.5) * texelSize);
o += tex2D(tex, uv + float2(-pixelOffset -0.5, pixelOffset +0.5) * texelSize);
o += tex2D(tex, uv + float2(-pixelOffset -0.5, -pixelOffset -0.5) * texelSize);
o += tex2D(tex, uv + float2(pixelOffset +0.5, -pixelOffset -0.5) * texelSize);
return o * 0.25;
}
//片元着色器代码块
float4 frag(v2f i): COLOR
{
float4 _Blur_1 = KawaseBlur(_MainTex, i.texcoord.xy, _MainTex_TexelSize.xy, _BlurSize);
//最终将结果
float4 FinalResult = _Blur_1;
FinalResult.rgb *= i.color.rgb;
FinalResult.a = FinalResult.a * _SpriteFade * i.color.a;
return FinalResult;
}
ENDCG
}
}
Fallback "Sprites/Default"
}
Shader "FoxShader/DualKawaseBlur"
{
//-----------------------------------【属性 || Properties】------------------------------------------
Properties
{
[PerRendererData] _MainTex ("Texture", 2D) = "white" { }
_BlurSize ("Blur Size", Range(0, 20)) = 2.0
}
//-------------------------CG着色语言声明部分 || Begin CG Include Part----------------------
CGINCLUDE
sampler2D _MainTex;
float4 _MainTex_TexelSize;//计算相邻像素的纹理坐标偏移量
half _BlurSize;
struct appdata
{
float4 vertex: POSITION;
float2 uv: TEXCOORD0;
};
struct v2f_DownSample
{
float4 vertex: SV_POSITION;
float2 uv[5]: TEXCOORD0;
};
struct v2f_UpSample
{
float4 vertex: SV_POSITION;
float2 uv[8]: TEXCOORD0;
};
//Pass1
//顶点着色器代码块
v2f_DownSample Vert_DownSample(appdata v)
{
v2f_DownSample o;
o.vertex = UnityObjectToClipPos(v.vertex);
half2 uv = v.uv;
_MainTex_TexelSize *= 0.5;
o.uv[0] = uv;
o.uv[1] = uv - _MainTex_TexelSize * float2(1 + _BlurSize, 1 + _BlurSize);//top right
o.uv[2] = uv + _MainTex_TexelSize * float2(1 + _BlurSize, 1 + _BlurSize);//bottom left
o.uv[3] = uv - float2(_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * float2(1 + _BlurSize, 1 + _BlurSize);//top left
o.uv[4] = uv + float2(_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * float2(1 + _BlurSize, 1 + _BlurSize);//bottom right
// o.uv[1] = uv + float2(_BlurSize + 0.5, _BlurSize + 0.5) * _MainTex_TexelSize.xy;
// o.uv[2] = uv + float2(-_BlurSize - 0.5, _BlurSize + 0.5) * _MainTex_TexelSize.xy;
// o.uv[3] = uv + float2(-_BlurSize - 0.5, -_BlurSize - 0.5) * _MainTex_TexelSize.xy;
// o.uv[4] = uv + float2(_BlurSize + 0.5, -_BlurSize - 0.5) * _MainTex_TexelSize.xy;
return o;
}
//片元着色器代码块
half4 Frag_DownSample(v2f_DownSample i): SV_Target
{
half4 sum = tex2D(_MainTex, i.uv[0]) * 4;
for (int it = 1; it < 5; it ++)
{
sum += tex2D(_MainTex, i.uv[it]);
}
return sum * 0.125;
}
//Pass2
//顶点着色器代码块
v2f_UpSample Vert_UpSample(appdata v)
{
v2f_UpSample o;
o.vertex = UnityObjectToClipPos(v.vertex);
half2 uv = v.uv;
_MainTex_TexelSize *= 0.5;
_BlurSize = float2(1 + _BlurSize, 1 + _BlurSize);
o.uv[0] = uv + float2(-_MainTex_TexelSize.x * 2, 0) * _BlurSize;
o.uv[1] = uv + float2(-_MainTex_TexelSize.x, _MainTex_TexelSize.y) * _BlurSize;
o.uv[2] = uv + float2(0, _MainTex_TexelSize.y * 2) * _BlurSize;
o.uv[3] = uv + _MainTex_TexelSize * _BlurSize;
o.uv[4] = uv + float2(_MainTex_TexelSize.x * 2, 0) * _BlurSize;
o.uv[5] = uv + float2(_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _BlurSize;
o.uv[6] = uv + float2(0, -_MainTex_TexelSize.y * 2) * _BlurSize;
o.uv[7] = uv - _MainTex_TexelSize * _BlurSize;
//偏移像素点
// o.uv[0] = uv + _MainTex_TexelSize.xy * half2(-2, 0) * _BlurSize;
// o.uv[1] = uv + _MainTex_TexelSize.xy * half2(-1, 1) * _BlurSize;
// o.uv[2] = uv + _MainTex_TexelSize.xy * half2(0, 2) * _BlurSize;
// o.uv[3] = uv + _MainTex_TexelSize.xy * _BlurSize;
// o.uv[4] = uv + _MainTex_TexelSize.xy * half2(2, 0) * _BlurSize;//原UV坐标
// o.uv[5] = uv + _MainTex_TexelSize.xy * half2(1, -1) * _BlurSize;
// o.uv[6] = uv + _MainTex_TexelSize.xy * half2(0, -2) * _BlurSize;
// o.uv[7] = uv - _MainTex_TexelSize.xy * _BlurSize;
return o;
}
//片元着色器代码块
half4 Frag_UpSample(v2f_UpSample i): SV_Target
{
half4 sum = 0;
for (int it = 1; it < 5; it ++)
{
sum += tex2D(_MainTex, i.uv[it * 2 - 2]);
sum += tex2D(_MainTex, i.uv[it * 2 - 1]) * 2;
}
return sum * 0.0833;
}
ENDCG
//-------------------结束CG着色语言声明部分 || End CG Programming Part-----------------
//----------------------------------【子着色器 || SubShader】---------------------------------------
SubShader
{
Tags { "RenderType" = "Transparent" "Queue" = "Transparent" "IgnoreProjector" = "True" "CanUseSpriteAtlas" = "True" "PreviewType" = "Plane" }
ZWrite Off ZTest Always Blend SrcAlpha OneMinusSrcAlpha Cull Off
Pass
{
NAME "GAUSSIAN_BLUR_VERTICAL"
CGPROGRAM
#pragma vertex Vert_DownSample
#pragma fragment Frag_DownSample
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
ENDCG
}
Pass
{
NAME "GAUSSIAN_BLUR_HORIZONTAL"
CGPROGRAM
#pragma vertex Vert_UpSample
#pragma fragment Frag_UpSample
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
ENDCG
}
}
Fallback off
}