后处理:屏幕热浪效果

实现一个基于屏幕后处理的热场空气扭曲效果,用来烘托战场氛围。原理其实非常简单,对于渲染完成的贴图做一个扰动效果即可。

代码(挂在主camera上才有效果):

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]

public class PostEffectBase : MonoBehaviour
{
    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) return null;

        if (shader.isSupported == false) return null;

        Material material = new Material(shader);
        material.hideFlags = HideFlags.DontSave;
        if (material != null)
            return material;

        return null;
    }
}

using UnityEngine;
using System.Collections;

public class ScreenWaveEffect : PostEffectBase
{
    [Range(-1f, 1f)]
    public float speedX = 0.1f;

    [Range(-1f, 1f)]
    public float speedY = 0.1f;

    [Range(0.0f, 1f)]
    public float strength = 0.1f;

    public Texture noiseTex;

    void OnRenderImage(RenderTexture src, RenderTexture dest)
    {
        if (_Material)
        {
            _Material.SetFloat("_speedX", speedX);
            _Material.SetFloat("_speedY", speedY);
            _Material.SetFloat("_strength", strength);
            _Material.SetTexture("_NoiseTex", noiseTex);

            Graphics.Blit(src, dest, _Material);
        }
        else
        {
            Graphics.Blit(src, dest);
        }
    }
}

屏幕效果shader:

Shader "James/ScreenEffect/ScreenWaveEffect"
{
    Properties
    {
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _NoiseTex("WaveTex (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Pass
        {
            ZTest Always Cull Off ZWrite Off

            CGPROGRAM
            sampler2D _MainTex, _NoiseTex;
            half4 _NoiseTex_ST;
            half _speedX, _speedY, _strength;

            #pragma vertex vert
            #pragma fragment frag
            #include "Lighting.cginc"

            struct v2f
            {
                float4 pos : SV_POSITION;
                half2  uv : TEXCOORD0;
            };

            v2f vert(appdata_img v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                half2 uvNoise = i.uv;
                uvNoise.x += _Time.y * _speedX;
                uvNoise.y += _Time.y * _speedY;
                fixed4 noiseTex = tex2D(_NoiseTex, uvNoise);
                
                half2 uvWave = i.uv + noiseTex.xy * _strength;
                fixed4 renderTex = tex2D(_MainTex, uvWave);

                return renderTex;
            }
            ENDCG
        }
    }
    FallBack Off
}

camera上脚本设置:

参数说明:

  shader:直接将上述shader拖过去即可

  speedx/speedy:横向和纵向扰动的速度

  strength:扰动的强度

  noise tex:噪音贴图(扰动贴图),决定了扰动的效果

运行效果如下:

说明:火焰贴图来自百度图片

 

posted @ 2018-11-18 12:59  斯芬克斯  阅读(1050)  评论(0编辑  收藏  举报