最近程序中要最做一个闪电鞭的效果,我用的uv操作实现的,话说操作纹理的uv,能实现的效果实在是太多了,比如最经典的序列帧动画。
大家都用过ngui吧我相信?我记得很以前老版本的ngui是没有直接提供uv动画功能类的,那时候我做uv动画是将美术给我的sprite列表打包成uiatlas,然后直接uiatlas = 序列帧atlas;uisprite.name = “sprite” + index.tostring();虽然实现了效果,但是基本上是基于ngui提供的功能,后面则直接让美术将序列帧ps成一张2的幂次方大图,保证sprite的等分摆放即可,如下:
这里特别提醒uv是左下角为(0,0),右上角为(1,1),我记得我说过的以前,那么接下来我们只需要for循环将整张图片根据uv偏移渲染即可,代码如下:
Shader "Unlit/uvUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_CellWidth("width",int) = 1
_CellHeight("height",int) = 1
_Speed("speed",Range(0.1,5.0)) = 1.0
}
SubShader
{
Tags { "RenderType"="Transparent" }
LOD 100
Pass
{
//支持透明混合渲染
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
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;
};
sampler2D _MainTex;
float4 _MainTex_ST;
int _CellWidth; //一行有4格
int _CellHeight; //一列也有4格
float _Speed; //给一个速度控制值
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//时间递增,使用int储存保证数值的间隔跳动
int time = _Time.y * _Speed;
//x偏移使用取模保证0-3
float x = time % _CellWidth;
//y偏移先确定行数,再取模0-3
float y = (time / _CellWidth)%_CellHeight;
//最后组装一个新的局部偏移uv
float2 uv = float2((i.uv.x + x)/(float)_CellWidth,(i.uv.y + y)/(float)_CellHeight);
fixed4 col = tex2D(_MainTex, uv);
return col;
}
ENDCG
}
}
}
达到的效果如下:
上面就是uv动画最常用的序列帧效果了。
下面再来一个闪电的效果,代码如下:
Shader "Unlit/uvFlashUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_XSpeed("xspeed",Range(0.1,10.0)) = 1.0
_YSpeed("yspeed",Range(0.1,10.0)) = 1.0
_XOffset("xoffset",Range(0,1.0)) = 1.0
_YOffset("yoffset",Range(0,1.0)) = 1.0
}
SubShader
{
Tags { "RenderType"="Transparent" }
LOD 100
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
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;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _XSpeed; //x偏移速度
float _YSpeed; //y偏移速度
float _XOffset; //x偏移幅度
float _YOffset; //y偏移幅度
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//x进行sin周期运动,y直接前向运动
float2 uv = float2(cos(_Time.y * _XSpeed) * _XOffset, _Time.y * _YSpeed * _YOffset);
i.uv += uv;
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
效果图如下:
当然图片是随便p的,没有那么完美的显示效果。
上面就是uv操作能达到的一些效果了,其他的uv效果看大家想象发挥。
so,我们接下来继续。