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);
 | 
						|
    }
 | 
						|
} |