Unity高斯模糊Shader
Posted nightfrost
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity高斯模糊Shader相关的知识,希望对你有一定的参考价值。
原理
这个shader姑且是根据自己的理解写的,如果有什么不对的评论区提醒一下咯,一般来说模糊和边缘检测这种效果是用卷积来实现的,可以通过使用不同的卷积核来获得图像的特征,模糊其实就是将计算的像素附近的像素乘上一定的权重加起来实现的效果,要保证这些权重的合为1,所以在计算出每个位置的权重后还要除以他们的平均值,用高斯函数的目的就是获得一个合理的权重,根据二维高斯函数的公式
可以把x^2 + y^2视为采样像素到中心像素的距离,所以代公式很容易可以得到二维高斯函数的值。
Shader "Hidden/Blurry"
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
_Sigma("Sigma", Range(1.0, 5.0)) = 1.5
_BlurRadius("BlurRadius", Range(1.0, 5.0)) = 3.0
}
CGINCLUDE
#include "UnityCG.cginc"
struct v2f_blur
{
float4 pos : SV_POSITION; //顶点位置
float2 uv : TEXCOORD0; //纹理坐标
};
//用到的变量
sampler2D _MainTex;
float4 _MainTex_TexelSize;
//模糊半径
float _BlurRadius;
// σ
float _Sigma;
//vertex shader
v2f_blur vert_blur(appdata_img v)
{
v2f_blur o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord.xy;
return o;
}
//fragment shader
fixed4 frag_blur(v2f_blur i) : SV_Target
{
fixed4 color = fixed4(0,0,0,0);
// 采样的9个像素点的偏移量
float2 offsets[9] =
{
float2(-1, 1), float2(0, 1), float2(1, 1),
float2(-1, 0), float2(0, 0), float2(1, 0),
float2(-1, -1), float2(0, -1), float2(1, -1),
};
float pi = 3.1415; // 圆周率
float e = 2.7182; // 数学常数
float sum = 0;
float weight[9];
// 卷积
for (int j = 0; j < 9; j++)
{
float l = length(_BlurRadius * _MainTex_TexelSize * offsets[j]); // 求距离
float g = (1.0 / (2.0 * pi * pow(_Sigma, 2.0))) * pow(e, (-(l * l) / (2.0 * pow(_Sigma, 2.0)))); // 高斯函数值
weight[j] = g;
sum += g;
}
for (int j = 0; j < 9; j++)
weight[j] /= sum;
for (int j = 0; j < 9; j++)
{
color += tex2D(_MainTex, i.uv + _BlurRadius * _MainTex_TexelSize * offsets[j]) * weight[j];
}
return color;
}
ENDCG
SubShader
{
Pass
{
ZTest Always
Cull Off
ZWrite Off
Fog{ Mode Off }
CGPROGRAM
#pragma vertex vert_blur
#pragma fragment frag_blur
ENDCG
}
}
}
将这个Shader作为后处理的Shader使用,可以得到效果:
Unity使用后处理相关的代码可以看这里
以上是关于Unity高斯模糊Shader的主要内容,如果未能解决你的问题,请参考以下文章
Unity Shader屏幕后处理3.0:均值模糊和高斯模糊
Unity Shader屏幕后处理4.0:基于高斯模糊的Bloom