1 均值模糊方案(一次均值)
Shader "Custom/Edu/SimpleBlur" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_BlurRadius("Blur Radius",Range(0,30)) = 5
}
CGINCLUDE
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _MainTex_TexelSize;
half _BlurRadius;
struct a2v
{
float4 vertex:POSITION;
float2 texcoord:TEXCOORD;
};
struct v2f
{
float4 pos:SV_POSITION;
half2 uv:TEXCOORD0;
half2 uv1:TEXCOORD1;
half2 uv2:TEXCOORD2;
half2 uv3:TEXCOORD3;
half2 uv4:TEXCOORD4;
};
v2f vert(a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.uv = v.texcoord;
o.uv1 = v.texcoord + half2(1,1) * _MainTex_TexelSize *_BlurRadius ;
o.uv2 = v.texcoord + half2(-1,1) * _MainTex_TexelSize *_BlurRadius ;
o.uv3 = v.texcoord + half2(1,-1) * _MainTex_TexelSize *_BlurRadius ;
o.uv4 = v.texcoord + half2(-1,-1) * _MainTex_TexelSize *_BlurRadius ;
return o;
}
fixed4 frag(v2f i):SV_Target
{
fixed4 color;
color = tex2D(_MainTex,i.uv) * _Color;
color += tex2D(_MainTex,i.uv1) * _Color;
color += tex2D(_MainTex,i.uv2) * _Color;
color += tex2D(_MainTex,i.uv3) * _Color;
color += tex2D(_MainTex,i.uv4) * _Color;
return color*0.2;
}
ENDCG
SubShader {
Pass
{
Tags{"LightMode" = "ForwardBase"}
ZTest Off
Cull Off
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
FallBack "Diffuse"
}
2 高斯模糊方案
均值模糊由于采样次数较少,每个像素以及其周围像素的权值是相同的,模糊出来的效果不佳,而多次迭代处理虽然可以增强模糊效果,但是迭代大大地增加了性能的消耗,虽然在学习时可以用迭代来达到效果,但是要实际使用的时候,效率就不得不成为我们考虑的重要因素。
高斯模糊就是在采样迭代的过程中在片元着色器内考虑各个采样点距离中心的远近,并乘以符合高斯分布的权重值。
Shader "Custom/Edu/GaussianBlur" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_BlurRadius("Blur Radius",Range(0,10)) = 5
_Color("Color Tint",Color)= (1,1,1,1)
}
CGINCLUDE
#include "unityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_TexelSize;
half _BlurRadius;
struct a2v
{
float4 vertex:POSTION;
float2 texcoord:TEXCOORD0;
};
struct v2f
{
float4 pos:SV_POSITION;
half2 uv[5]:TEXCOORD0;
};
v2f vertBlurVertical(a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.uv[0] = v.texcoord ;
o.uv[1] = v.texcoord + _BlurRadius * float2(0,1) * _MainTex_TexelSize;
o.uv[2] = v.texcoord + _BlurRadius * float2(0,-1) * _MainTex_TexelSize;
o.uv[3] = v.texcoord + _BlurRadius * float2(0,2) * _MainTex_TexelSize;
o.uv[4] = v.texcoord + _BlurRadius * float2(0,-2) * _MainTex_TexelSize;
return o;
}
v2f vertBlurHorizontal(a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.uv[0] = v.texcoord ;
o.uv[1] = v.texcoord + _BlurRadius * float2(1,0) * _MainTex_TexelSize;
o.uv[2] = v.texcoord + _BlurRadius * float2(-1,0) * _MainTex_TexelSize;
o.uv[3] = v.texcoord + _BlurRadius * float2(2,0) * _MainTex_TexelSize;
o.uv[4] = v.texcoord + _BlurRadius * float2(-2,0) * _MainTex_TexelSize;
return o;
}
fixed4 fragBlur(v2f i):SV_Target
{
float weight[3] = {0.4026,0.2442,0.0545};
fixed3 sum = tex2D(_MainTex,i.uv[0]).rgb * weight[0];
// 为什么不用i呢?因为传入的v2f变量实参的名称就是 i !
for(int it=1; it<3; it++){
sum += tex2D(_MainTex, i.uv[2*it]).rgb * weight[it];
sum += tex2D(_MainTex, i.uv[2*it-1]).rgb * weight[it];
}
return fixed4(sum,1.0);
}
ENDCG
SubShader {
Tags { "RenderType"="Opaque" }
ZTest Always
Cull Off
ZWrite Off
Pass
{
//潜意识中的错误写法,不需要等号
//NAME = "vertBlurVertical"
NAME "vertBlurVertical"
CGPROGRAM
#pragma vertex vertBlurVertical
#pragma fragment fragBlur
ENDCG
}
Pass
{
NAME "vertBlurHorizontal"
CGPROGRAM
#pragma vertex vertBlurHorizontal
#pragma fragment fragBlur
ENDCG
}
}
FallBack "Diffuse"
}