一:效果演示

Shader——热扰动效果_C


二:实现

Shader:热扰动着色器

//热扰动着色器

Shader "Distortion"
{
	Properties
	{
		_MainTex("Base (RGB)", 2D) = "white" {}
	}
		SubShader
	{
		Zwrite Off
		Cull Off

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

			uniform sampler2D _MainTex;
			uniform sampler2D _NoiseTex;
			uniform sampler2D _MaskTex;
			uniform float _DistortStrength;
			uniform float _DistortVelocity;
			uniform float _XDensity;
			uniform float _YDensity;
			
			fixed4 frag(v2f_img i) : SV_Target
			{
				//通过缩放纹理控制噪声纹理密度,改变扰动密集感
				float2  _NoiseUV = i.uv*float2(_XDensity,_YDensity);
				//根据时间因素从而获得不断变化的噪点值,增加热扰动流动感
				float2 offset = tex2D(_NoiseTex, _NoiseUV -_Time.y * _DistortVelocity).xy;
				//原取得的值在0到1,重映射到-1到1,增加扰动方向的随机感,并用_DistortStrength更改采样偏移距离,控制扰动强度
				offset = (offset - 0.5) * 2 * _DistortStrength;
				//采样偏移量乘上采样遮罩的值,该值为0到1,既遮罩白色部分正常扰动,黑色部分无扰动,中间灰色则为过度
				i.uv += offset*tex2D(_MaskTex, i.uv).x;
				return tex2D(_MainTex, i.uv);
			}
			ENDCG
		}
	}
}

CS:后处理的基类

using UnityEngine;

/// <summary>
/// 后处理的基类
/// </summary>
[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class PostEffectBase : MonoBehaviour
{
    [Header("后处理着色器")]
    public Shader shader = null;

    private Material _material = null;

    public Material material
    {
        get
        {
            if (_material == null)
            {
                _material = GenerateMaterial(shader);
            }
            return _material;
        }
    }

    protected Material GenerateMaterial(Shader shader)
    {
        if (shader == null || shader.isSupported == false)
        {
            return null;
        }
        Material material = new Material(shader);
        material.hideFlags = HideFlags.DontSave;
        if (material)
        {
            return material;
        }
        return null;
    }
}

CS:热扰动效果(挂载到渲染的相机上)

using UnityEngine;

/// <summary>
/// 热扰动效果
/// </summary>
[RequireComponent(typeof(Camera))]
public class Distortion : PostEffectBase
{
    [Header("噪声纹理")]
    public Texture NoiseTexture = null;

    [Header("遮罩纹理")]
    public Texture MaskTexture = null;

    [HideInInspector]
    [Header("扭曲的时间系数")]
    [Range(0.0f, 1.0f)]
    [Space(25)]
    public float DistortTimeFactor = 0.15f;

    [HideInInspector]
    [Range(0, 1)]
    [Header("热扰动速率")]
    public float DistortVelocity = 0.5f;

    [Range(-1, 1)]
    [Header("热扰动强度")]
    [Space(25)]
    public float DistortStrength = 0.8f;

    [Header("噪声竖直密度")]
    public float YDensity = 1.0f;

    [Header("噪声水平密度")]
    public float XDensity = 1.0f;

    private void OnRenderImage(RenderTexture source, RenderTexture dest)
    {
        if (material)
        {
            material.SetTexture("_NoiseTex", NoiseTexture);
            material.SetTexture("_MaskTex", MaskTexture);
            material.SetFloat("_DistortTimeFactor", DistortTimeFactor);
            material.SetFloat("_DistortStrength", DistortStrength);
            material.SetFloat("_YDensity", YDensity);
            material.SetFloat("_XDensity", XDensity);
            Graphics.Blit(source, dest, material);
        }
        else
        {
            Graphics.Blit(source, dest);
        }
    }
}

——设置后处理着色器,噪声纹理、遮罩纹理等参数,如果不设置遮罩纹理则默认为全屏热扰动,设置遮罩纹理则遮罩白色部分正常扰动,黑色部分无扰动
Shader——热扰动效果_2d_02
Shader——热扰动效果_2d_03