文章目录
- 前言
- 一、U方向的走格
- 1、 要实现移动的效果,我们就会想到使用_Time
- 2、使用floor向下取整
- 3、把x、y缩小为原函数的 Column倍
- 4、使用_Sequence的z控制帧动画U方向上的速度
- 二、U方向的走格
- 三、最终效果
- 1、亚丝娜
- 2、小蓝帽
- 3、火
- 4、最终代码
前言
在上一篇文章中,我们定位了通用的Shader序列帧动画的通用起始点位置。
- Unity中Shader序列图动画(UV流动的通用起始点)
在这篇文章中,我们实现一下在U方向上的走格。
一、U方向的走格
1、 要实现移动的效果,我们就会想到使用_Time
o.uv.x +=_Time.y;
- 但是,直接相加使用的话,会实现如下效果,不是我们想要的走格子
-
f
(
t
)
=
t
f(t) =t
f(t)=t
2、使用floor向下取整
o.uv.x += floor(_Time.y);
- 这样实现了加格子的效果。但是,看不见Shader移动了
- f ( t ) = t f(t) = t f(t)=t
- g ( t ) = ⌊ f ( t ) ⌋ = ⌊ t ⌋ g(t) = \lfloor f(t) \rfloor = \lfloor t \rfloor g(t)=⌊f(t)⌋=⌊t⌋
- 由图中可看出,u方向看不出移动的原因:因为每次加的值都是1的倍数。
- 所以,当对应到[0,1]的uv值时,就看不出移动了
3、把x、y缩小为原函数的 Column倍
o.uv.x += floor(_Time.z *_Sequence.y)/_Sequence.y;
- 这样就可以实现 U 方向的走格效果了
-
u
(
t
)
=
g
(
C
o
l
u
m
n
⋅
t
)
C
o
l
u
m
n
=
⌊
C
o
l
u
m
n
⋅
t
⌋
C
o
l
u
m
n
u(t) = \frac{g(Column·t)}{Column} = \frac{\lfloor Column·t \rfloor}{Column}
u(t)=Columng(Column⋅t)=Column⌊Column⋅t⌋
4、使用_Sequence的z控制帧动画U方向上的速度
_Sequence(“Row(X) Column(Y) Speed(Z)”,Vector) = (1,1,1,1)
o.uv.x += floor(_Time.z * _Sequence.z *_Sequence.y )/_Sequence.y;
二、U方向的走格
-
因为,我们需要实现走完一行再走下一行的效果。
-
所以,就需要把 v 方向上的 x 扩大到原来的 Colum(列) 倍
-
v ( t ) = u ( t C o l u m n ) = ⌊ C o l u m n ⋅ t C o l u m n ⌋ C o l u m n v(t) = u(\frac{t}{Column}) = \frac{\lfloor \frac{Column·t}{Column} \rfloor}{Column} v(t)=u(Columnt)=Column⌊ColumnColumn⋅t⌋
-
并且,因为 v 方向是从上到下移动
-
所以,这里需要减去该函数值而不是加上
o.uv.y -= floor(_Time.y *_Sequence.y * _Sequence.z / _Sequence.y)/_Sequence.x;
三、最终效果
1、亚丝娜
2、小蓝帽
3、火
4、最终代码
Shader "MyShader/URP/P3_9"
{
Properties
{
_Color("Color",Color) = (1,1,1,1)
_MainTex("MainTex",2D) = "white"{}
_Sequence("Row(X) Column(Y) Speed(Z)",Vector) = (1,1,1,1)
}
SubShader
{
Tags
{
//告诉引擎,该Shader只用于 URP 渲染管线
"RenderPipeline"="UniversalPipeline"
//渲染类型
"RenderType"="Transparent"
//渲染队列
"Queue"="Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha Zwrite On
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attribute
{
float3 vertexOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varying
{
float4 vertexCS : SV_POSITION;
float2 uv : TEXCOORD1;
float fogCoord : TEXCOORD2;
};
CBUFFER_START(UnityPerMaterial)
float4 _Color;
float4 _MainTex_ST;
half4 _Sequence;
CBUFFER_END
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
Varying vert(Attribute v)
{
Varying o;
o.vertexCS = TransformObjectToHClip(v.vertexOS);
o.uv = float2(v.uv.x/_Sequence.y,v.uv.y/_Sequence.x + (_Sequence.x - 1)/_Sequence.x);
o.uv.x += floor(_Time.y *_Sequence.y * _Sequence.z)/_Sequence.y;
o.uv.y -= floor(_Time.y *_Sequence.y * _Sequence.z / _Sequence.y)/_Sequence.x;
//o.uv.x += floor(_Time.y);
//o.uv = float2(v.uv.x/4,v.uv.y/4);
//o.uv = TRANSFORM_TEX(v.uv,_MainTex);
o.fogCoord = ComputeFogFactor(o.vertexCS.z);
return o;
}
half4 frag(Varying i) : SV_Target
{
float4 mainTex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv);
float4 col = mainTex * _Color;
col.rgb = MixFog(col,i.fogCoord);
return col;
}
ENDHLSL
}
}
}