使用 高斯核 对像素进行模糊处理
- 脚本
using System;
using UnityEngine;
public class GaussianBlur : PostEffectBase
{
public Shader gaussianBlurShader;
[Range(0.2f, 3f)]
public float blurSpread;
[Range(1, 8)]
public int downSample = 2;
[Range(0, 4)]
public int iterations = 3;
private Material _gaussianBlurMaterial;
public Material material
{
get
{
_gaussianBlurMaterial = CheckShaderAndCreateMaterial(gaussianBlurShader, _gaussianBlurMaterial);
return _gaussianBlurMaterial;
}
}
private void OnRenderImage(RenderTexture src, RenderTexture dest)
{
if (material != null)
{
int rtw = src.width / downSample;
int rth = src.height / downSample;
//Shader: Pass0 : 横线 Gx Pass : 垂直 Gy
RenderTexture buffer0 = RenderTexture.GetTemporary(rtw, rth, 0);
buffer0.filterMode = FilterMode.Bilinear;
for (int i = 0; i < iterations; i++)
{
material.SetFloat("_BlurSize", 1.0f + i * blurSpread);
RenderTexture buffer1 = RenderTexture.GetTemporary(rtw, rth, 0);
Graphics.Blit(src, buffer1, material, 0);
RenderTexture.ReleaseTemporary(buffer0);
buffer0 = buffer1;
buffer1 = RenderTexture.GetTemporary(rtw, rth, 0);
Graphics.Blit(buffer0, buffer1, material, 1);
RenderTexture.ReleaseTemporary(buffer0);
buffer0 = buffer1;
}
Graphics.Blit(buffer0, dest);
RenderTexture.ReleaseTemporary(buffer0);
}
else Graphics.Blit(src, dest);
}
}
- shader
Shader "Hidden/GaussianBlur"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {
}
_BlurSize ("BlurSize", Float) = 1.0
}
SubShader
{
CGINCLUDE
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv[5] : TEXCOORD0;
};
sampler2D _MainTex;
half4 _MainTex_TexelSize;
float _BlurSize;
v2f vertBlurHorizontal (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float2 uv = v.uv;
o.uv[0] = uv + float2(0.0 * _MainTex_TexelSize.x, 0.0) * _BlurSize;
o.uv[1] = uv + float2(1.0 * _MainTex_TexelSize.x, 0.0) * _BlurSize;
o.uv[2] = uv + float2(-1.0 * _MainTex_TexelSize.x, 0.0) * _BlurSize;
o.uv[3] = uv + float2(2.0 * _MainTex_TexelSize.x, 0.0) * _BlurSize;
o.uv[4] = uv + float2(-2.0 * _MainTex_TexelSize.x, 0.0) * _BlurSize;
return o;
}
v2f vertBlurVertical (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
float2 uv = v.uv;
o.uv[0] = uv + float2(0.0, 0.0 * _MainTex_TexelSize.y) * _BlurSize;
o.uv[1] = uv + float2(0.0, 1.0 * _MainTex_TexelSize.y) * _BlurSize;
o.uv[2] = uv + float2(0.0, -1.0 * _MainTex_TexelSize.y) * _BlurSize;
o.uv[3] = uv + float2(0.0, 2.0 * _MainTex_TexelSize.y) * _BlurSize;
o.uv[4] = uv + float2(0.0, -2.0 * _MainTex_TexelSize.y) * _BlurSize;
return o;
}
fixed4 fragBlur (v2f i) : SV_Target
{
float weight[3] = {
0.4026, 0.2442, 0.0545};
fixed3 color = tex2D(_MainTex, i.uv[0]).rgb * weight[0];
for (int it = 1; it < 3; it++)
{
color += tex2D(_MainTex, i.uv[2 * it - 1]).rgb * weight[it];
color += tex2D(_MainTex, i.uv[2 * it]).rgb * weight[it];
}
return fixed4(color, 1.0);
}
ENDCG
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
NAME "GAUSSIANBLUR_HORIZONTAL"
CGPROGRAM
#pragma vertex vertBlurHorizontal
#pragma fragment fragBlur
ENDCG
}
Pass
{
NAME "GAUSSIANBLUR_VERTICAL"
CGPROGRAM
#pragma vertex vertBlurVertical
#pragma fragment fragBlur
ENDCG
}
}
FallBack Off
}