Unity 点击特效(Shader)水、燃烧

方法一:(特效预制体)

新建特效预制体,放在Resources文件夹下

using UnityEngine;

public class ClickEffect : MonoBehaviour {
        Vector3 point;
        GameObject effectGo;
	
	void Start () {
          effectGo = Resources.Load<GameObject>("Prefabs/EffectClick");
	}
	
	void Update () {
      //点击鼠标特效
        if (Input.GetMouseButtonDown(0))
        {
            point = new Vector3(Input.mousePosition.x,Input.mousePosition.y,4f);//获得鼠标点击点
            point = Camera.main.ScreenToWorldPoint(point);//从屏幕空间转换到世界空间
            GameObject go = Instantiate(effectGo);//生成特效
            go.transform.position = point;
            Destroy(go, 0.5f);
        }
    }
}

方法二:(水波纹效果)shader篇

shader文件

 

Shader "Unlit/ClickEffect"// Shader中的位置这个最后一个名字要和你创的Shader名字一样
{
    Properties
    {
        _MainTex("Base (RGB)", 2D) = "white" {}
    }
 
        CGINCLUDE
#include "UnityCG.cginc"
    uniform sampler2D _MainTex;
    float4 _MainTex_TexelSize;
    uniform float _distanceFactor;  //距离系数
    uniform float _timeFactor;      //时间系数
    uniform float _totalFactor;     //sin函数结果系数
 
    uniform float _waveWidth;       //波纹宽度
    uniform float _curWaveDis;      //扩散速度
    uniform float4 _startPos;       //开始位置
 
    fixed4 frag(v2f_img i) : SV_Target
    {
        //DX下纹理坐标反向问题
        //UNITY_UV_STARTS_AT_TOP总是用1或0定义,Direct3D平台为1,OpenGL平台为0
        //在Direct3D中,坐标顶点为零,向下增加
        //OpenGL坐标底部为零,向上增加
#if UNITY_UV_STARTS_AT_TOP
        if (_MainTex_TexelSize.y < 0)
        _startPos.y = 1 - _startPos.y;
#endif
    //计算uv到中间点的向量(向外扩,反过来就是向里缩)
    float2 dv = _startPos.xy - i.uv;
    //按照屏幕长宽比进行缩放
    dv = dv * float2(_ScreenParams.x / _ScreenParams.y, 1);
    //计算像素点距中点的距离
    float dis = sqrt(dv.x * dv.x + dv.y * dv.y);
    //用sin函数计算出波形的偏移值factor
    //dis在这里都是小于1的,所以我们需要乘以一个比较大的数,比如60,这样就有多个波峰波谷
    //sin函数是(-1,1)的值域,我们希望偏移值很小,所以这里我们缩小100倍,据说乘法比较快,so...
    float sinFactor = sin(dis * _distanceFactor + _Time.y * _timeFactor) * _totalFactor * 0.01;
    //距离当前波纹运动点的距离,如果小于waveWidth才予以保留,否则已经出了波纹范围,factor通过clamp设置为0
    float discardFactor = clamp(_waveWidth - abs(_curWaveDis - dis), 0, 1) / _waveWidth;
    //归一化
    float2 dv1 = normalize(dv);
    //计算每个像素uv的偏移值
    float2 offset = dv1  * sinFactor * discardFactor;
    //像素采样时偏移offset
    float2 uv = offset + i.uv;
    return tex2D(_MainTex, uv);
    }
        ENDCG
 
        SubShader
    {
        Pass
        {
            ZTest Always
            Cull Off
            ZWrite Off
            Fog{ Mode off }
 
            CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest 
            ENDCG
        }
    }
    Fallback off

}

 

控制文件 (挂到摄像机上)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
//非运行时也出发效果
[ExecuteInEditMode]
public class WaterWave : MonoBehaviour {
 
    //Inspector面板上直接拖入
    public Shader shader = null;
    private Material _material = null;
 
    //距离系数
    public float distanceFactor = 60.0f;
    //时间系数
    public float timeFactor = -30.0f;
    //sin函数结果系数
    public float totalFactor = 1.0f;
 
    //波纹宽度
    public float waveWidth = 0.3f;
    //波纹扩散的速度
    public float waveSpeed = 0.3f;
 
    private float waveStartTime;
    private Vector4 startPos = new Vector4(0.5f, 0.5f, 0, 0);
 
    //根据Shader生成材质
    public Material _Material
    {
        get
        {
            if (_material == null)
                _material = GenerateMaterial(shader);
            return _material;
        }
    }
 
    //根据shader创建用于屏幕特效的材质
    protected Material GenerateMaterial(Shader shader)
    {
        if (shader == null)
            return null;
        //需要判断shader是否支持
        if (shader.isSupported == false)
            return null;
        Material material = new Material(shader);
        material.hideFlags = HideFlags.DontSave;
        if (material)
            return material;
        return null;
    }
 
    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        //计算波纹移动的距离,根据enable到目前的时间*速度求解
        float curWaveDistance = (Time.time - waveStartTime) * waveSpeed;
        //设置一系列参数
        _Material.SetFloat("_distanceFactor", distanceFactor);
        _Material.SetFloat("_timeFactor", timeFactor);
        _Material.SetFloat("_totalFactor", totalFactor);
        _Material.SetFloat("_waveWidth", waveWidth);
        _Material.SetFloat("_curWaveDis", curWaveDistance);
        _Material.SetVector("_startPos", startPos);
        Graphics.Blit(source, destination, _Material);
    }
 
    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            Vector2 mousePos = Input.mousePosition;
            //将mousePos转化为(0,1)区间
            startPos = new Vector4(mousePos.x / Screen.width, mousePos.y / Screen.height, 0, 0);
            waveStartTime = Time.time;
        }
    }
}

 

方法三:燃烧消失特效(需要两个贴图,一张噪点)

Shader "Custom/FireEffect" {
	Properties{
		_Color("主颜色", Color) = (1,1,1,1)                       // 主色  
		_MainTex("模型贴图", 2D) = "white" {}                      // 主材质  
		_DissolveText("溶解贴图", 2D) = "white" {}                 // 溶解贴图  
		_Tile("溶解贴图的平铺大小", Range(0, 1)) = 1                // 平铺值,设置溶解贴图大小  

		_Amount("溶解值", Range(0, 1)) = 0.5                     // 溶解度  
		_DissSize("溶解大小", Range(0, 1)) = 0.1                   // 溶解范围大小  

		_DissColor("溶解主色", Color) = (1,1,1,1)                  // 溶解颜色  
		_AddColor("叠加色,与主色叠加为开始色[R|G|B>0表示启用]", Color) = (1,1,1,1) // 改色与溶解色融合形成开始色  
	}

	SubShader{

		Tags { "RenderType" = "Opaque" }
		LOD 200
		Cull off

		CGPROGRAM
		#pragma target 3.0  
		#pragma surface surf BlinnPhong  

		sampler2D _MainTex;
		sampler2D _DissolveText;
		fixed4 _Color;          // 主色  
		half _Tile;             // 平铺值  
		half _Amount;           // 溶解度  
		half _DissSize;         // 溶解范围  
		half4 _DissColor;       // 溶解颜色   
		half4 _AddColor;        // 叠加色  
		// 最终色  
		static half3 finalColor = float3(1,1,1);

		struct Input {
			float2 uv_MainTex;  // 只需要主材质的UV信息  
		};

		void surf(Input IN, inout SurfaceOutput o) {
			// 对主材质进行采样  
			fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
			// 设置主材质和颜色  
			o.Albedo = tex.rgb * _Color.rgb;
			// 对裁剪材质进行采样,取R色值  
			float ClipTex = tex2D(_DissolveText, IN.uv_MainTex / _Tile).r;

			// 裁剪量 = 裁剪材质R - 外部设置量  
			float ClipAmount = ClipTex - _Amount;
			if (_Amount > 0)
			{
				// 如果裁剪材质的R色值 < 设置的裁剪值  那么此点将被裁剪  
				if (ClipAmount < 0)
				{
					clip(-0.1);
				}
				// 然后处理没有被裁剪的值  
				else
				{
					// 针对没有被裁剪的点,【裁剪量】小于【裁剪大小】的做处理  
					// 如果设置了叠加色,那么该色为ClipAmount/_DissSize(这样会形成渐变效果)  
					if (ClipAmount < _DissSize)
					{
						if (_AddColor.x == 0)
							finalColor.x = _DissColor.x;
						else
							finalColor.x = ClipAmount / _DissSize;

						if (_AddColor.y == 0)
							finalColor.y = _DissColor.y;
						else
							finalColor.y = ClipAmount / _DissSize;

						if (_AddColor.z == 0)
							finalColor.z = _DissColor.z;
						else
							finalColor.z = ClipAmount / _DissSize;
						// 融合  
						o.Albedo = o.Albedo * finalColor * 2;
					}
				}
			}
			o.Alpha = tex.a * _Color.a;
		}
		ENDCG
	}
}

大兄弟,如果文章对您有帮助的话,可不可以点个赞啊~

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值