Unity Shader 之 简单实现沙漠干旱热浪的效果

2025-11-13 06:14:49

1、打开Unity,新建一个空工程,在场景中添加一个Cube,具体如下图

Unity Shader 之 简单实现沙漠干旱热浪的效果

Unity Shader 之 简单实现沙漠干旱热浪的效果

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

Unity Shader 之 简单实现沙漠干旱热浪的效果

Unity 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自旋转使用,双击脚本你进行编辑代码,具体如下图

Unity Shader 之 简单实现沙漠干旱热浪的效果

Unity Shader 之 简单实现沙漠干旱热浪的效果

Unity Shader 之 简单实现沙漠干旱热浪的效果

Unity Shader 之 简单实现沙漠干旱热浪的效果

Unity Shader 之 简单实现沙漠干旱热浪的效果

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上,对应赋值,具体如下图

Unity Shader 之 简单实现沙漠干旱热浪的效果

Unity Shader 之 简单实现沙漠干旱热浪的效果

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

Unity Shader 之 简单实现沙漠干旱热浪的效果

Unity Shader 之 简单实现沙漠干旱热浪的效果

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢