Unity制作护盾——1、闪电护盾

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 OneMinusSrcAlpha
		ZWrite Off
        LOD 100

        Pass
        {
            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
        }
    }
}

猜你喜欢

转载自blog.csdn.net/liweizhao/article/details/132131907