制作前准备
- 需求要求
- UI中的一张图片需要无限制的斜向移动。
- 图片设置准备
开始制作
首先我们需要一个mainTexture的参数和调节速度的参数,所以我们在Properties块中定义2个属性,代码如下:
Properties {
_MainTex ("Main Texture", 2D) = "black" {}
_speed ("speed", Range(0, 10)) = 0.5
}
然后我们设立一个结构体v2f来存储转换位置后的数据,代码如下:
struct v2f {
float4 pos : SV_POSITION;
half2 uvTA: TEXCOORD0;
};
其中:
float4 pos : SV_POSITION 表示转换后的顶点位置,half2 uvTA: TEXCOORD0 表示转换后的顶点纹理坐标。
接着我们开始具体的转换,代码如下:
v2f vert(appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uvTA = v.texcoord;
return o;
}
其中,appdata_img v 表示输入的顶点数据,包含了顶点的位置和纹理坐标等信息。v.vertex 表示顶点的位置,v.texcoord 表示顶点的纹理坐标。
mul(UNITY_MATRIX_MVP, v.vertex) 表示将顶点的位置乘以当前的模型视图投影矩阵(MVP 矩阵)进行转换,得到转换后的顶点位置。
最后,将转换后的顶点位置和纹理坐标打包成一个 v2f 结构体,并返回转换后的数据,进行uv偏移的操作,代码如下:
fixed4 frag(v2f i) : SV_Target {
float2 uv = i.uvTA;
uv.x -= _Time.y * _speed;
uv.y -= _Time.y * _speed;
if (uv.x > 1.0 || uv.y > 1.0) {
uv.x -= 1.0;
uv.y -= 1.0;
}
if (uv.x < 0.0 || uv.y < 0.0) {
uv.x += 1.0;
uv.y += 1.0;
}
return tex2D(_MainTex, uv).rgba ;
}
最后实现的效果
因为是UI所以需要挂在画布下
效果Gif如下:
shader全部代码:
Shader "TUT/BackgroundLoop_P1" {
Properties {
_MainTex ("Main Texture", 2D) = "black" {}
_speed ("speed", Range(0, 10)) = 0.5
}
SubShader {
Tags {"Queue"="Transparent" }
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
uniform half4 _MainTex_ST;
struct v2f {
float4 pos : SV_POSITION;
half2 uvTA: TEXCOORD0;
};
v2f vert(appdata_img v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uvTA = v.texcoord;
return o;
}
float _speed;
fixed4 frag(v2f i) : SV_Target {
float2 uv = i.uvTA;
uv.x -= _Time.y * _speed;
uv.y -= _Time.y * _speed;
if (uv.x > 1.0 || uv.y > 1.0) {
uv.x -= 1.0;
uv.y -= 1.0;
}
if (uv.x < 0.0 || uv.y < 0.0) {
uv.x += 1.0;
uv.y += 1.0;
}
return tex2D(_MainTex, uv).rgba ;
}
ENDCG
Pass {
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
FallBack "Diffuse"
}