Unity引擎制作闪电护盾效果
大家好,我是阿赵。
这期做一个闪电护盾的效果。
一、效果说明
可以改变闪电的颜色
可以改变范围
改变贴图的平铺次数,也可以做出各种不同感觉的护盾。
二、原理
这个效果看着很复杂,其实只是用了一张Noise贴图
把贴图贴在一个球上,得到这样的效果
常规操作,先乘再power,得到一个可以控制亮度和范围的效果。
这里我想这个效果是流动起来的。所以可以选择用UV动画来做。我这里做一个稍微复杂一点的UV动画,叫做Flow效果:
float3 Flow(sampler2D tex, float2 uv, float2 dir, float2 strength, float speed)
{float2 dirx = dir + 0.5f;float timeSpeed = _Time.y*speed;float2 uv1 = uv + (dirx*strength*frac(timeSpeed));float2 uv2 = uv + (dirx*strength*(frac(timeSpeed + 0.5f)));float3 result = lerp(UnpackNormal(tex2D(tex, uv1)), UnpackNormal(tex2D(tex, uv2)), (abs((frac(timeSpeed) - 0.5)) / 0.5));return result;
}
通过传入贴图、uv、流动方向、流动强度和速度,得到一个流动的动画效果。
对上面的效果继续做power和取反(被1减)的操作,得到这样的一个效果,我们拿到的是刚才那个噪声图的边缘。
接下来我们再做一次Flow,但这次传入的dir是不同的。然后把两次的结果相乘,得到这么一个随机变化的遮罩。
给rgb乘以一个颜色,就得到了这个护盾的基础颜色了
然后把遮罩给到alpha通道,就看到了这样的效果了。
如果想闪电有一定的闪烁效果,那么简单的用Time作为x,0作为y,组成UV采样一下给噪声图。就能得到一个闪烁的过程,这个值乘以原来的Alpah通道。
三、代码
Shader "azhao/azhaoShield1"
{Properties{_Size("Size", Range(0 , 10)) = 1_colorPow("colorPow", Float) = 1_colorMul("colorMul", Float) = 1_mainColor("mainColor", Color) = (1,1,1,0)_Noise1Tex("Noise1Tex", 2D) = "white" {}_dir1("dir1", Vector) = (0,0,0,0)_dir2("dir2", Vector) = (1,1,0,0)_alphaSpeed("alphaSpeed", Float) = 1_colorAdd("colorAdd", Float) = 1_flowSpeed("flowSpeed", Float) = 1_flowStrength("flowStrength", Vector) = (1,1,0,0)}SubShader{Tags { "RenderType"="Opaque" }Blend SrcAlpha OneMinusSrcAlpha, SrcAlpha OneMinusSrcAlphaZWrite OffLOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};uniform float4 _mainColor;uniform sampler2D _Noise1Tex;uniform float4 _Noise1Tex_ST;uniform float _Size;uniform float3 _dir1;uniform float2 _flowStrength;uniform float _flowSpeed;uniform float _colorMul;uniform float _colorPow;uniform float3 _dir2;uniform float _colorAdd;uniform float _alphaSpeed;float3 Flow(sampler2D tex, float2 uv, float2 dir, float2 strength, float speed){float2 dirx = dir + 0.5f;float timeSpeed = _Time.y*speed;float2 uv1 = uv + (dirx*strength*frac(timeSpeed));float2 uv2 = uv + (dirx*strength*(frac(timeSpeed + 0.5f)));float3 result = lerp(UnpackNormal(tex2D(tex, uv1)), UnpackNormal(tex2D(tex, uv2)), (abs((frac(timeSpeed) - 0.5)) / 0.5));return result;}v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _Noise1Tex)/+_Size;return o;}half4 frag (v2f i) : SV_Target{float3 col1 = Flow(_Noise1Tex,i.uv,_dir1,_flowStrength,_flowSpeed);float3 col2 = Flow(_Noise1Tex, i.uv, _dir2, _flowStrength, _flowSpeed);float val1 = 1.0 - saturate( pow(col1.r*_colorMul, _colorPow));float val2 = 1.0 - saturate(pow(col2.r*_colorMul, _colorPow));float4 noiseCol = tex2D(_Noise1Tex, float2(frac(_Time.y*_alphaSpeed), 0));float alpha = val1*val2*noiseCol.r*noiseCol.r;float3 rgb = _mainColor.rgb*val1*val2*_colorAdd;return half4(rgb,alpha);}ENDCG}}
}