Unity3D Shader 空气扭动效果

//预览图

 

//原理

一个摄像机CullingMask设置只可见"Distortion"的Layer(需要自己手动加),输入到一张RenderTexture,其实就是用于确定哪里要扭曲。

另外一个摄像机CullingMask设置成对除了"Distortion"的Layer可见,并挂上后期效果脚本。

 

//Shader代码

Shader "Hidden/Distortion"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Noise ("Noise", 2D) = "black" {}
        _DistortionMask ("Distortion Mask", 2D) = "black" {}
        _DistortionStrength ("Distortion Strength", Float) = 0.1
        _DistortTimeFactor ("_Distort Time Factor", Float) = 0.1
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = v.uv;
                return o;
            }
            
            sampler2D _MainTex;

            sampler2D _DistortionMask;
            sampler2D _Noise;
            float _DistortionStrength;
            float _DistortTimeFactor;

            fixed4 frag (v2f i) : SV_Target
            {
                //wave strength
                fixed strength = tex2D(_DistortionMask, i.uv).r;

                //noise
                fixed2 noi = tex2D(_Noise, i.uv-fixed2(0,_Time.y * _DistortTimeFactor));

                //uv offset
                fixed2 uvOffset = strength*noi.xy*_DistortionStrength;

                fixed4 col = tex2D(_MainTex, i.uv.xy+uvOffset.xy);

                return col;
            }
            ENDCG
        }
    }
}

 

//C#代码

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class DistortionPostEffect : MonoBehaviour 
{
    private Camera distortionCam;
    public Material DistortionMat;
    private RenderTexture rt;
    void Awake()
    {
        Transform go = transform.Find("Distortion");
        if (null == go) {
            go = (new GameObject ("Distortion")).transform;
        }
        go.transform.parent = transform;
        go.transform.localPosition = Vector3.zero;
        go.transform.rotation = Quaternion.identity;


        distortionCam = go.GetComponent<Camera> ();
        if (null == distortionCam) {
            distortionCam = go.gameObject.AddComponent<Camera> ();
        }
        distortionCam.clearFlags = CameraClearFlags.Color;
        distortionCam.backgroundColor = Color.black;
        //rt = RenderTexture.GetTemporary (Screen.width / 2, Screen.height / 2);
        rt = RenderTexture.GetTemporary (200 , 100);
        rt.wrapMode = TextureWrapMode.Repeat;
        distortionCam.targetTexture = rt;
        distortionCam.cullingMask = LayerMask.GetMask ("Distortion");

        gameObject.GetComponent<Camera> ().cullingMask &=  (~distortionCam.cullingMask);
    }
    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
    
    }

    void OnRenderImage(RenderTexture src,RenderTexture dest)
    {
        DistortionMat.SetTexture ("_DistortionMask", rt);
        Graphics.Blit (src, dest, DistortionMat);
    }


}

 

posted @ 2017-10-26 23:36  MrBlue  阅读(1978)  评论(0编辑  收藏  举报