Unity Shader 之 简单实现沙漠干旱热浪的效果
1、打开Unity,新建一个空工程,在场景中添加一个Cube,具体如下图


2、在工程中导入一张云图,作为噪点热浪渲染图,新建一个shader,并且,打开进行编辑,具体如下图


3、HotWave.shader 的具体代码和说明如下:
Shader "Custom/HotWave" {
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
_NoiseTex("Noise (RGB)", 2D) = "white" {}
_LuminosityAmount("GrayScale Amount", Range(0.0, 1.0)) = 1.0
_DistortTimeFactor("DistortTimeFactor", Range(0,1)) = 1
}
SubShader
{
Pass{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D _NoiseTex;
fixed _LuminosityAmount;
float _DistortTimeFactor;
fixed4 frag(v2f_img i) : COLOR
{
float4 noise = tex2D(_NoiseTex, i.uv - _Time.xy * _DistortTimeFactor);
float2 offset = noise.xy * _LuminosityAmount;
return tex2D(_MainTex, i.uv + offset);
}
ENDCG
}
}
FallBack "Diffuse"
}
4、回到Unity,在新建两个脚本,控制shader和Cube自旋转使用,双击脚本你进行编辑代码,具体如下图





5、CameraHotWave 脚本具体代码和代码说明如下:
using UnityEngine;
/// <summary>
/// 实现相机热浪效果
/// </summary>
[ExecuteInEditMode] // 编辑状态下执行该类
[RequireComponent(typeof(Camera))] // 要求有相机
public class CameraHotWave : MonoBehaviour {
public Shader curShader; // shader变量参数
public Texture noise; // 噪点图片
[Range(0.0f, 1.0f)]
public float grayScaleAmount = 0.1f; // 主图扭曲范围参数
[Range(0.0f, 1.0f)]
public float DistortTimeFactor = 0.15f; // 主图扭曲热浪动态变化速度参数
private Material curMaterial; // 材质参数
public Material material // 材质参数属性
{
get
{
// 材质为空,新建材质,并赋予热浪 shader
if (curMaterial == null)
{
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return curMaterial;
}
}
void Start()
{
// 判断系统是否支持图像特效
if (SystemInfo.supportsImageEffects == false)
{
enabled = false;
return;
}
// 判断当前shader 是否为空,是否支持
if (curShader != null && curShader.isSupported == false)
{
enabled = false;
}
}
/// <summary>
/// 图片渲染函数
/// Camera的一个回调(message),他会在camera执行渲染时候被调用
/// </summary>
/// <param name="sourceTexture">原图片</param>
/// <param name="destTexture">目标图片</param>
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
// 判断当前shader是否为空
// 不为空则设置控制赋值对用的shader参数,进行渲染
// 为空则不带 Material 渲染
if (curShader != null)
{
material.SetFloat("_LuminosityAmount", grayScaleAmount);
material.SetFloat("_DistortTimeFactor", DistortTimeFactor);
material.SetTexture("_NoiseTex", noise);
Graphics.Blit(sourceTexture, destTexture, material);
}
else
{
Graphics.Blit(sourceTexture, destTexture);
}
}
void Update()
{
// 保证值不越界在[0,1]范围
grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
}
void OnDisable()
{
// 失效时销毁新建的材质
if (curMaterial != null)
{
DestroyImmediate(curMaterial);
}
}
}
6、RotateBySelf 脚本具体代码和代码说明如下:
using UnityEngine;
public class RotateBySelf : MonoBehaviour {
public float speed = 60.0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.Rotate(Vector3.up, Time.deltaTime * speed );
}
}
7、脚本编译正确,回到Unity,把 CameraHotWave 脚本挂载到相机上,并且对应赋值,把 RotateBySelf 脚本挂载到Cube上,对应赋值,具体如下图


8、运行场景,热浪效果如下图,并且可以通过修改 CameraHotWave 俩阈值来调整热浪效果,具体如下图

