Shader 屏幕后期特效 Shake(震屏)&Wave(波纹)

震屏效果


 

Shader:

////////////////////////////////////////////
///// CameraPlay - by VETASOFT 2017    /////
////////////////////////////////////////////

Shader "CameraPlay/Shake" { 
Properties 
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_TimeX ("Time", Range(0.0, 1.0)) = 1.0
_ScreenResolution ("_ScreenResolution", Vector) = (0.,0.,0.,0.)
}
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 _Value;
uniform float _Value2;
uniform float _Value3;
uniform float4 _ScreenResolution;
struct appdata_t
{
float4 vertex   : POSITION;
float4 color    : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 texcoord  : TEXCOORD0;
float4 vertex   : SV_POSITION;
float4 color    : COLOR;
};
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color;
return OUT;
}

float nrand(float2 n) 
{
return frac(sin(dot(n.xy, float2(12.9898, 78.233)))* 43758.5453);
}

float4 frag (v2f i) : COLOR
{
float2 uv = i.texcoord.xy;
float t = float(int(_TimeX * _Value));
float2 suv = float2(0,0);
suv.x = uv.x + _Value2 * nrand(t);
suv.y = uv.y + _Value3 * nrand(t + 23.0);
suv.x -=_Value2/2;
suv.y -=_Value3/2;
float3 col = tex2D(_MainTex,suv).rgb;
return float4(col,1.0);
}
ENDCG
}
}
}
View Code

Controller:

////////////////////////////////////////////
///// CameraPlay - by VETASOFT 2017    /////
////////////////////////////////////////////

using UnityEngine;

public class ShakeController : MonoBehaviour
{
    [HideInInspector] public Shader m_shader;
    private float m_time = 1.0f;
    private Vector4 m_screenResolution;
    private Material m_material;
    [HideInInspector] public float m_value = 0.5f;
    [HideInInspector] public float m_size = 1f;
    [HideInInspector] public float m_duration = 1f;
    [HideInInspector] private float m_timer = 1f;
    [HideInInspector] public float m_speed = 15f;
    
    Material material
    {
        get
        {
            if (m_material == null)
            {
                m_material = new Material(m_shader);
                m_material.hideFlags = HideFlags.HideAndDontSave;
            }
            return m_material;
        }
    }
    void Awake()
    {
        m_value = 0;
        m_timer = 0;
        m_shader = Shader.Find("CameraPlay/Shake");
        if (!SystemInfo.supportsImageEffects)
        {
            enabled = false;
            Debug.Log("手机不支持后处理...");
            return;
        }

        m_duration = 0.2f;
        m_speed = 30;
        m_size = 1;
    }

    // Start Animation
    void OnEnable()
    {
        m_value = 0;
        m_timer = 0;
    }


    void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
    {
        if (m_shader != null)
        {
            m_time += Time.deltaTime;
            if (m_time > 100) m_time = 0;
            material.SetFloat("_TimeX", m_time);
            material.SetFloat("_Value", m_speed);
            material.SetFloat("_Value2", m_size * 0.008f);
            material.SetFloat("_Value3", m_size * 0.008f);
            material.SetVector("_ScreenResolution", new Vector4(sourceTexture.width, sourceTexture.height, 0.0f, 0.0f));
            Graphics.Blit(sourceTexture, destTexture, material);
        }
        else
        {
            Graphics.Blit(sourceTexture, destTexture);
        }
    }
    void Update()
    {

        m_timer += Time.deltaTime * (1 / m_duration);
        if (m_timer > 1.1f) /*Object.Destroy(this);*/
            this.enabled = false;
    }
    void OnDisable()
    {
        if (m_material)
        {
            DestroyImmediate(m_material);
        }
    }
}
View Code

使用方法:

  1.Shader和Controller拖进项目。Shader还要丢到Edit - Project Settings -Graphics 的Always included Shaders 中

  2.摄像机上挂载对应脚本,控制脚本的Enable属性即可

杂谈:

  Shader控制震屏比animation控制更简单,而且不易出错

 

波纹效果


 

 

 

Shader:

////////////////////////////////////////////
///// CameraPlay - by VETASOFT 2017    /////
////////////////////////////////////////////

Shader "CameraPlay/ShockWave"
{
    Properties
    {
        _MainTex("Base (RGB)", 2D) = "white" {}
        _TimeX("Time", Range(0.0, 1.0)) = 1.0
        _ScreenResolution("_ScreenResolution", Vector) = (0.,0.,0.,0.)
    }
        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 _Value;
        uniform float _Value2;
        uniform float _Value3;
        uniform float _Value4;
        uniform float4 _ScreenResolution;
        uniform float2 _MainTex_TexelSize;

    struct appdata_t
    {
        float4 vertex   : POSITION;
        float4 color    : COLOR;
        float2 texcoord : TEXCOORD0;
    };
    struct v2f
    {
        float2 texcoord  : TEXCOORD0;
        float4 vertex   : SV_POSITION;
        float4 color : COLOR;
    };
    v2f vert(appdata_t IN)
    {
        v2f OUT;
        OUT.vertex = UnityObjectToClipPos(IN.vertex);
        OUT.texcoord = IN.texcoord;
        OUT.color = IN.color;
        return OUT;
    }
    float4 frag(v2f i) : COLOR
    {
        float2 uv = i.texcoord.xy;
        float2 uv2 = uv;
        #if UNITY_UV_STARTS_AT_TOP
        if (_MainTex_TexelSize.y < 0)
        uv.y = 1 - uv.y;
        #endif
        float Dist = distance(uv, float2(_Value, _Value2));
        float Diff = (Dist - _Value3);
        float v = (1.0 - pow(abs(Diff * 10.0), 0.8));
        float vt = v * 0.02 * _Value4;
        vt = saturate(vt);
        uv2.x = uv2.x - vt;
        uv2.y = uv2.y - vt;
        float4 Color = tex2D(_MainTex, uv2);
        Color.rgb += float3(vt, vt, vt);
        

        
        return Color;
    }
        ENDCG
    }
    }
}
View Code

Controller:

/***************************************
Editor: Tason
Version: v1.0
Last Edit Date: 2018-XX-XX 
Tel: 328791554@qq.com
Function Doc: 

***************************************/

using UnityEngine;

public class WaveController : MonoBehaviour 
{
    [HideInInspector] public Shader m_shader;
    private float m_time = 1.0f;
    private Vector4 m_screenResolution;
    private Material m_material;
    [HideInInspector] public float m_posX = 0.5f;
    [HideInInspector] public float m_posY = 0.5f;
    [HideInInspector] public float m_value = 0.5f;
    [HideInInspector] public float m_size = 1f;
    [HideInInspector] public float m_duration = 1f;
    [HideInInspector] private float m_timer = 1f;

    Material material
    {
        get
        {
            if (m_material == null)
            {
                m_material = new Material(m_shader);
                m_material.hideFlags = HideFlags.HideAndDontSave;
            }
            return m_material;
        }
    }

    void Awake()
    {
        m_value = 0;
        m_timer = 0;
        m_shader = Shader.Find("CameraPlay/ShockWave");
        if (!SystemInfo.supportsImageEffects)
        {
            enabled = false;
            Debug.Log("手机不支持后处理...");
            return;
        }

        m_posX = 0.5f;
        m_posY = 0.5f;
        m_duration = 1.5f * 2;
        m_size = 1;
    }

    void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
    {
        if (m_shader != null)
        {
            m_time += Time.deltaTime;
            if (m_time > 100) m_time = 0;
            material.SetFloat("_TimeX", m_time);
            material.SetFloat("_Value", m_posX);
            material.SetFloat("_Value2", m_posY);
            material.SetFloat("_Value3", m_value);
            material.SetFloat("_Value4", m_size);
            material.SetVector("_ScreenResolution", new Vector4(sourceTexture.width, sourceTexture.height, 0.0f, 0.0f));
            Graphics.Blit(sourceTexture, destTexture, material);
        }
        else
        {
            Graphics.Blit(sourceTexture, destTexture);
        }
    }

    void OnEnable()
    {
        m_value = 0;
        m_timer = 0;
    }

    private void Update()
    {
        m_timer += Time.deltaTime * (1 / m_duration);
        if (m_timer > 1.1f)
            //Object.Destroy(this);
            this.enabled = false;
            
        m_value = m_timer;
    }

    void OnDisable()
    {
        if (m_material)
        {
            DestroyImmediate(m_material);
        }
    }
}
View Code

使用方法同“震屏”(同上)

资源链接:

  链接:https://pan.baidu.com/s/1ZcSskWxi3wMgYOU9rg4o-g 密码:vzfn

 

修改:

  1.Ondisable 中注释掉 DestroyImmediate() 函数!不需要销毁材质!

 

posted on 2018-08-22 09:54  未闻花语  阅读(1648)  评论(0编辑  收藏  举报