Unity3D Shdaer 实现镜头模糊效果[Shader]

原文链接: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"
}


C#代码:

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

    }

}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值