效果:
【太妃糖耶】更新了一条视频,快来围观!
序列图动画的实现
首先先了解下序列图样式的纹理图片
如上图一可在Shader中使用该图片制作燃烧的火的动画,但是如何实现呢?接下来一起来看一下吧
序列图动画的实现原理大概是顺序采样序列图纹理中的每一个小格子块,从最上方的左边开始一直到最右边然后再继续下一行的采样,从而形成动画效果
所以序列图动画的实现分为两个步骤:
1.首先采样最上方左侧小格子中的纹理
2.完成UV的走格,通过变化的UV来采样对应的格子块从而形成动画效果
第一步:采样最上方左侧小格子中的纹理
o.uv = float2(v.uv.x/_Column,v.uv.y/_Row+1/_Row*(_Row-1));
其中_Row代表行数,_Column代表列数 (两者必须为float类型)
上面的代码相当于 v.uv.x=v.uv.x/_Column; v.uv.y=v.uv.y/_Row+1/_Row*(_Row-1);
v.uv.x=v.uv.x/_Column; 用原UV中U方向的值除以列数,得到新的U方向上的值(如果列数为3,U方向上的值则为(0,0.333))
v.uv.y=v.uv.y/_Row+1/_Row*(_Row-1); 用原UV中V方向的值除以行数,表示一个小格子中U方向的值。再加上1/_Row*(_Row-1)代表将U方向的值移动到原UV中V方向的最上侧。
第二步:完成UV走格,通过变化的UV来采样对应的格子块从而形成动画效果
首先我们可以用o.uv.x+=_Time.y;来看一下效果(可见不是我们想要的走格的效果)
- U方向的走格:
o.uv.x += frac(floor(_Time.y*_Column*_Speed)/_Column);
floor(_Time.y*_Column)/_Column : 实现一秒之内完成一行的走格
- V方向的走格:
o.uv.y - = frac(floor(_Time.y*_Speed)/_Row);
floor(_Time.y)/_Row : 每秒向下偏移一格(用减法实现向下偏移)
frac取小数的作用是优化纹理采样,使得采样纹理的UV在0-1的范围内
实现透贴效果
Tags{"Queue"="Transparent"}
当序列图为透贴格式时,使用 Blend SrcAlpha OneMinusSrcAlpha 来实现背景透明
还可以在片元着色器中使用 c.rgb *= c.a; , 透明区域的a通道中的值为0,所以此时透明背景就变为黑色,所以要配合 Blend One One 来使用
若序列图的背景是黑色时,可以使用 Blend One One
综上所述,可以使用 c.rgb *= c.a 和 Blend One One 共同实现透贴图片和黑底图片的半透明效果
Shader"unity/UV"
{Properties{[NoScaleOffset]_MainTex("MainTex",2D)="white"{}_Row("Row",float)=1_Column("Column",float)=1_Speed("Speed",float)=3[Enum(Billaboard,1,VerticalBillaboard,0)]_BillaboardType("BillaboardType",int)=1}SubShader{Tags{"RenderPipeline"="UniversalPipeline""Queue"="Transparent"}//常用于透贴// Blend SrcAlpha OneMinusSrcAlpha//用于黑底图片Blend One OnePass{HLSLPROGRAM#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"#pragma vertex vert#pragma fragment fragTEXTURE2D(_MainTex);float4 _MainTex_ST;#define sampler_MainTex samplerState_Linear_RepeatSAMPLER(sampler_MainTex);CBUFFER_START(UnityPerMaterial)float _Row,_Column,_Speed;int _BillaboardType;CBUFFER_ENDstruct Attributes{float4 positionOS : POSITION;float2 uv : TEXCOORD;};struct Varyings{float4 positionCS : SV_POSITION;float2 uv : TEXCOORD;};Varyings vert(Attributes v){Varyings o = (Varyings)0;o.positionCS = TransformObjectToHClip(v.positionOS);o.uv = TRANSFORM_TEX(v.uv,_MainTex);//序列图动画的起始位置o.uv = float2(v.uv.x/_Column,v.uv.y/_Row+1/_Row*(_Row-1));//frac取小数的作用是优化纹理采样,使得采样纹理的UV在0-1的范围内//U方向上的走格 floor(_Time.y*_Column)/_Column代表一秒钟走完一行中的所以列的格子o.uv.x+=frac(floor(_Time.y*_Column*_Speed)/_Column);//V方向上的走格 floor(_Time.y)/_Row 代表每一秒走一行o.uv.y-=frac(floor(_Time.y*_Speed)/_Row);return o;}float4 frag(Varyings i):SV_Target{float4 c;float4 mainTex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv);c=mainTex;//用于透贴图片消除Alpah为0的区域 Alpha=1为不透明,Alpha=0为透明c.rgb*=c.a;return c;}ENDHLSL}}}