原文链接:http://www.manew.com/thread-98523-1-1.html
效果如下:
shader代码:
Shader "Custom/CameraFilterPack_Blur_Movie"
{
Properties
{
_MainTex("Base(RGB)", 2D) = "white" {}
_TimeX("Time", Range(0.0, 1.0)) = 1.0
_Distortion("_Distortion", Range(0.0, 1.0)) = 0.3
_ScreenResolution("_ScreenResolution", Vector) = (0.0, 0.0, 0.0, 0.0)
_Radius("_Radius", Range(0.0, 1000.0)) = 700
_Factor("_Factor", Range(0.0, 1000.0)) = 200
}
SubShader
{
Pass
{
ZTest Always
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma target 3.0
#pragma glsl
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float _TimeX;
uniform float _Distortion;
uniform float4 _ScreenResolution;
uniform float _Radius;
uniform float _Factor;
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
half2 texcoord : TEXCOORD0;
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
};
v2f vert(appdata_t IN)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
o.texcoord = IN.texcoord;
o.color = IN.color;
return o;
}
#define tex2D(sampler, uvs) tex2Dlod(sampler, float4((uvs), 0.0f, 0.0f))
float4 frag(v2f i) : COLOR
{
float factor = _Factor / _ScreenResolution.y * 64.0;
float radius = _Radius / _ScreenResolution.x * 2.0;
float4 col = 0.0;
float4 accumColx = 0.0;
float4 accumW = 0.0;
for(float j = -5.0; j < 5.0; j += 1.0)
{
for(float u = -5.0; u < 5.0; u += 1.0)
{
float2 offsetx = (1.0 / _ScreenResolution.xy) * float2(u + j, j - u);
col = tex2D(_MainTex, i.texcoord.xy + offsetx * radius);
float4 movie = 1.0 + col * col * col * factor;
accumColx = accumColx + col * movie;
accumW += movie;
}
}
accumColx = accumColx / accumW;
return accumColx;
}
ENDCG
}
}
FallBack "Diffuse"
}
using UnityEngine;
[ExecuteInEditMode]
[AddComponentMenu("Camera Filter Pack/Blur/Movie")]
public class CameraFilterPack_Blur_Movie : MonoBehaviour
{
#region Variables
public Shader SCShader;
private float TimeX = 1.0f;
private Vector4 ScreenResolution;
private Material SCMaterial;
[Range(0, 1000)]
public float Radius = 150.0f;
[Range(0, 1000)]
public float Factor = 200.0f;
[Range(1, 8)]
public int FastFilter = 2;
public static float ChangeRadius;
public static float ChangeFactor;
public static int ChangeFastFilter;
#endregion
#region Properties
Material material
{
get
{
if (SCMaterial == null)
{
SCMaterial = new Material(SCShader);
SCMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return SCMaterial;
}
}
#endregion
void Start()
{
ChangeRadius = Radius;
ChangeFactor = Factor;
ChangeFastFilter = FastFilter;
SCShader = Shader.Find("Custom/CameraFilterPack_Blur_Movie");
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
}
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
if (SCShader != null)
{
int DownScale = FastFilter;
TimeX += Time.deltaTime;
if (TimeX > 100) TimeX = 0;
material.SetFloat("_TimeX", TimeX);
material.SetFloat("_Radius", Radius / DownScale);
material.SetFloat("_Factor", Factor);
material.SetVector("_ScreenResolution", new Vector2(Screen.width / DownScale, Screen.height / DownScale));
int rtW = sourceTexture.width / DownScale;
int rtH = sourceTexture.height / DownScale;
if (FastFilter > 1)
{
RenderTexture buffer = RenderTexture.GetTemporary(rtW, rtH, 0);
Graphics.Blit(sourceTexture, buffer, material);
Graphics.Blit(buffer, destTexture);
RenderTexture.ReleaseTemporary(buffer);
}
else
{
Graphics.Blit(sourceTexture, destTexture, material);
}
}
else
{
Graphics.Blit(sourceTexture, destTexture);
}
}
void OnValidate()
{
ChangeRadius = Radius;
ChangeFactor = Factor;
ChangeFastFilter = FastFilter;
}
// Update is called once per frame
void Update()
{
if (Application.isPlaying)
{
Radius = ChangeRadius;
Factor = ChangeFactor;
FastFilter = ChangeFastFilter;
}
#if UNITY_EDITOR
if (Application.isPlaying != true)
{
SCShader = Shader.Find("Custom/CameraFilterPack_Blur_Movie");
}
#endif
}
void OnDisable()
{
if (SCMaterial)
{
DestroyImmediate(SCMaterial);
}
}
}