Unity渲染(三):Shader着色器基础入门之模糊(Blur)
时间:2022-12-31 12:00:00
Unity渲染(3):Shader模糊
通过这里,你将学习如何使图片更加模糊
上一章:Unity渲染(2):Shader着色器基础入门渲染Image图片
开发环境:Unity5.0或者更高
概述
1. 模糊原理 2. 解释和实
现代码 3. 完整代码 4. 使用
1.1 模糊原理
当前像素颜色改为周围像素颜色的平均值,离当前像素越远,权重越低,效果越好
例如 上图的1格子
最终颜色为:八种2格子
十六种颜色3格子
的颜色 除24外,这是均值模糊。
如果将3格子
加上颜色0.3
加上2格子
的颜色乘以0.7
,这就是越远的格子分配更低的权重,看起来效果会更好。接下来用Shader代码实现:
1.2 代码实现
首先,我们需要传输三个参数来定义模糊函数:
sampler2D tex
表示需要模糊的图像
half2 uv
表示需要模糊图像uv坐标
half2 blurSize
表示需要取周围像素的范围
KERNEL_SIZE
表示模糊,值越大,效果越好,算法越复杂。对应上述格子图,取2格子的平均值,或取2格子 3格子的甲醛平均值,或更大范围的4格子的加权平均值
fixed4 Blur(sampler2D tex, half2 uv, half2 blurSize) {
int KERNEL_SIZE = 3; int KERNEL_SIZE = 3; float4 o = 0; float sum = 0; float weight; half2 texcood; for(int x = -KERNEL_SIZE/2; x <= KERNEL_SIZE/2; x ) {
for(int y = -KERNEL_SIZE/2; y <= KERNEL_SIZE/2; y ) {
texcood = uv; texcood.x = blurSize.x * x; texcood.y = blurSize.y * y;
weight = 1.0/(abs(x)+abs(y)+2);
o += tex2D(tex, texcood)*weight;
sum += weight;
}
}
return o / sum;
}
在片元着色器中使用:
_MainTex
表示samper2D 的主贴图
_MainTex_TexelSize
表示主贴图的像素大小,由Unity内置 xxx_TexelSize
_Radius
表示需要模糊的半径,定义在Properties
fixed4 frag(v2f i) : SV_TARGET
{
fixed4 col = Blur(_MainTex,i.uv,_Radius * _MainTex_TexelSize.xy);
return col;
}
1.3 完整代码
Shader "Toturial/BlurPro"
{
Properties
{
_MainTex("MainTex",2D) = "white"{
}
_Color("Color",Color) = (1,1,1,1)
_Radius("半径",Range(0,10)) = 0
}
SubShader
{
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float _Radius;
struct a2v
{
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
fixed4 color : COLOR;
float2 uv : TEXCOORD0;
};
fixed4 Blur (sampler2D tex, half2 uv, half2 blurSize)
{
int KERNEL_SIZE = 3;
float4 o = 0;
float sum = 0;
float weight;
half2 texcood;
for(int x = -KERNEL_SIZE/2; x <= KERNEL_SIZE/2; x++)
{
for(int y = -KERNEL_SIZE/2; y <= KERNEL_SIZE/2; y++)
{
texcood = uv;
texcood.x += blurSize.x * x;
texcood.y += blurSize.y * y;
weight = 1.0/(abs(x)+abs(y)+2);
o += tex2D(tex, texcood)*weight;
sum += weight;
}
}
return o / sum;
}
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.uv = v.uv;
return o;
}
fixed4 frag(v2f i) : SV_TARGET
{
fixed4 col = Blur(_MainTex,i.uv,_Radius * _MainTex_TexelSize.xy);
return col;
}
ENDCG
}
}
}
1.4 使用
创建一个材质命名为Toturial_BlurPro
,选择刚才编写的shader,
将材质赋给Sprite2D 或者Image,即可看到最终效果