文章目录
- 前言
- 一、一般序列帧动画是按照序列图如下顺序读取的
- 二、在Shader找到UV流动的起始点
- 1、先实现纹理采样
- 2、得到 uv 走格的单位格子大小
- 3、定位到左上角为起始单位格
- 三、使UV流动的起始点通用化
- 1、在属性面板接收 行 和 列的属性
- 2、看图片可以总结出第一个单元格的公式
- 3、我们选几个不同的序列图看看效果
- 四、测试代码
前言
我们在Shader中实现序列帧动画。可以实现一些简单特效或动画节省性能用。
我们在这篇文章中,实现一下UV流动的通用起始点。
一、一般序列帧动画是按照序列图如下顺序读取的
- 先左到右,再从上到下
二、在Shader找到UV流动的起始点
1、先实现纹理采样
-
Unity中 URP Shader 的纹理与采样器的分离定义
-
属性面板
_MainTex(“MainTex”,2D) = “white”{}
- 定义纹理
TEXTURE2D(_MainTex);
- 定义采样器
SAMPLER(sampler_MainTex);
- 在片元着色器进行纹理采样
float4 mainTex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv);
2、得到 uv 走格的单位格子大小
- 是 m ∗ n m * n m∗n 的序列帧图,就对UV除以多少,来得到一个格子的图像
u m 和 v n \frac{u}{m} 和 \frac{v}{n} mu和nv - 比如说,我们使用如下 4 x 4 的序列帧来测试
就对 uv 分别除以4得到一个序列图的大小
o.uv = float2(v.uv.x/4,v.uv.y/4);
3、定位到左上角为起始单位格
- 可以看出,我们的 u 方向以及在起始位置了,但是 v 方向却在最后一列
- 所以,我们需要加上 n - 1 个单位格大小,使 v 方向上达到第一行
o.uv = float2(v.uv.x/4,v.uv.y/4 + 0.75);
三、使UV流动的起始点通用化
1、在属性面板接收 行 和 列的属性
_Sequence(“Row(X) Column(Y)”,Vector) = (1,1,1,1)
2、看图片可以总结出第一个单元格的公式
- u v . x = u v . x C o l u m n uv.x = \frac{uv.x}{Column} uv.x=Columnuv.x
- u v . y = u v . y R o w + R o w − 1 R o w uv.y = \frac{uv.y}{Row}+\frac{Row-1}{Row} uv.y=Rowuv.y+RowRow−1
o.uv = float2(v.uv.x/_Sequence.y,v.uv.y/_Sequence.x + (_Sequence.x - 1)/_Sequence.x);
3、我们选几个不同的序列图看看效果
-
4x3
-
4x4
四、测试代码
Shader "MyShader/URP/P3_9"
{Properties{_Color("Color",Color) = (1,1,1,1)_MainTex("MainTex",2D) = "white"{}_Sequence("Row(X) Column(Y)",Vector) = (1,1,1,1)}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}Blend SrcAlpha OneMinusSrcAlpha Zwrite OnPass{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_ENDTEXTURE2D(_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 = 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}}}