131 lines
4.0 KiB
C#
131 lines
4.0 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
|
|
[ExecuteInEditMode]
|
|
[AddComponentMenu("Image Effects/Blur")]
|
|
public class BlurEffect : MonoBehaviour
|
|
{
|
|
/// Blur iterations - larger number means more blur.
|
|
public int iterations = 3;
|
|
|
|
/// Blur spread for each iteration. Lower values
|
|
/// give better looking blur, but require more iterations to
|
|
/// get large blurs. Value is usually between 0.5 and 1.0.
|
|
public float blurSpread = 0.6f;
|
|
|
|
|
|
// --------------------------------------------------------
|
|
// The blur iteration shader.
|
|
// Basically it just takes 4 texture samples and averages them.
|
|
// By applying it repeatedly and spreading out sample locations
|
|
// we get a Gaussian blur approximation.
|
|
|
|
private static string blurMatString =
|
|
@"Shader ""BlurConeTap"" {
|
|
Properties { _MainTex ("""", any) = """" {} }
|
|
SubShader {
|
|
Pass {
|
|
ZTest Always Cull Off ZWrite Off Fog { Mode Off }
|
|
SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant alpha}
|
|
SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
|
|
SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
|
|
SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
|
|
}
|
|
}
|
|
Fallback off
|
|
}";
|
|
|
|
static Material m_Material = null;
|
|
protected static Material material
|
|
{
|
|
get
|
|
{
|
|
if (m_Material == null)
|
|
{
|
|
m_Material = new Material(blurMatString);
|
|
m_Material.hideFlags = HideFlags.HideAndDontSave;
|
|
m_Material.shader.hideFlags = HideFlags.HideAndDontSave;
|
|
}
|
|
return m_Material;
|
|
}
|
|
}
|
|
|
|
protected void OnDisable()
|
|
{
|
|
if (m_Material)
|
|
{
|
|
DestroyImmediate(m_Material.shader);
|
|
DestroyImmediate(m_Material);
|
|
}
|
|
}
|
|
|
|
// --------------------------------------------------------
|
|
|
|
protected void Start()
|
|
{
|
|
// Disable if we don't support image effects
|
|
if (!SystemInfo.supportsImageEffects)
|
|
{
|
|
enabled = false;
|
|
return;
|
|
}
|
|
// Disable if the shader can't run on the users graphics card
|
|
if (!material.shader.isSupported)
|
|
{
|
|
enabled = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Performs one blur iteration.
|
|
public void FourTapCone(RenderTexture source, RenderTexture dest, int iteration)
|
|
{
|
|
float off = 0.5f + iteration * blurSpread;
|
|
Graphics.BlitMultiTap(source, dest, material,
|
|
new Vector2(-off, -off),
|
|
new Vector2(-off, off),
|
|
new Vector2(off, off),
|
|
new Vector2(off, -off)
|
|
);
|
|
}
|
|
|
|
// Downsamples the texture to a quarter resolution.
|
|
private void DownSample4x(RenderTexture source, RenderTexture dest)
|
|
{
|
|
float off = 1.0f;
|
|
Graphics.BlitMultiTap(source, dest, material,
|
|
new Vector2(-off, -off),
|
|
new Vector2(-off, off),
|
|
new Vector2(off, off),
|
|
new Vector2(off, -off)
|
|
);
|
|
}
|
|
|
|
// Called by the camera to apply the image effect
|
|
void OnRenderImage(RenderTexture source, RenderTexture destination)
|
|
{
|
|
RenderTexture buffer = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0);
|
|
RenderTexture buffer2 = RenderTexture.GetTemporary(source.width / 4, source.height / 4, 0);
|
|
|
|
// Copy source to the 4x4 smaller texture.
|
|
DownSample4x(source, buffer);
|
|
|
|
// Blur the small texture
|
|
bool oddEven = true;
|
|
for (int i = 0; i < iterations; i++)
|
|
{
|
|
if (oddEven)
|
|
FourTapCone(buffer, buffer2, i);
|
|
else
|
|
FourTapCone(buffer2, buffer, i);
|
|
oddEven = !oddEven;
|
|
}
|
|
if (oddEven)
|
|
ImageEffects.Blit(buffer, destination);
|
|
else
|
|
ImageEffects.Blit(buffer2, destination);
|
|
|
|
RenderTexture.ReleaseTemporary(buffer);
|
|
RenderTexture.ReleaseTemporary(buffer2);
|
|
}
|
|
} |