一:效果演示
二:实现
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);
}
}
}
——设置后处理着色器,噪声纹理、遮罩纹理等参数,如果不设置遮罩纹理则默认为全屏热扰动,设置遮罩纹理则遮罩白色部分正常扰动,黑色部分无扰动