《Unity Shader》11.2.1 序列帧动画

为了在Unity中实现序列帧动画,我们需要做如下准备工作。

(1)新建一个场景。在本书资源中,该场景名为Scene_11_2_1。在Unity 5.2中,默认情况下场景将包含一个摄像机和一个平行光,并且使用了内置的天空盒子。在Window → Lighting →Skybox中去掉场景中的天空盒子。

(2)新建一个材质。在本书资源中,该材质名为ImageSequenceAnimationMat。

(3)新建一个Unity Shader。在本书资源中,该Shader名为Chapter11-ImageSequenceAnimation。把新的Shader赋给第2步中创建的材质。

(4)在场景中创建一个四边形(Quad),调整它的位置使其正面朝向摄像机,并把第2步中的材质拖给曳它。

上述序列帧动画的精髓在于,我们需要在每个时刻计算该时刻下应该播放的关键帧的位置,并对该关键帧进行纹理采样。打开新建的Chapter11-ImageSequenceAnimation,删除原有的代码,并添加如下关键代码。

(1)我们首先声明了多个属性,以设置该序列帧动画的相关参数:

(2)由于序列帧图像通常是透明纹理,我们需要设置Pass的相关状态,以渲染透明效果:

(3)顶点着色器的代码非常简单,我们进行了基本的顶点变换,并把顶点纹理坐标存储到了v2f结构体里:

(4)片元着色器是我们的重头戏:

(5)最后,我们把Fallback设置为内置的Transparent/VertexLit(也可以选择关闭Fallback):

保存后返回场景,我们将Assets/Textures/Chapter11/Boom.png(注意,由于是透明纹理,因此需要勾选该纹理的Alpha Is Transparency属性)赋给ImageSequenceAnimationMat中的Image Sequence属性,并将Horizontal Amount和Vertical Amount设置为8(因为Boom.png包含了8行8列的关键帧图像),完成后单击播放,并调整Speed属性,就可以得到一段连续的爆炸动画。

https://github.com/candycat1992/Unity_Shaders_Book/blob/master/Assets/Shaders/Chapter11/Chapter11-ImageSequenceAnimation.shader

cs 复制代码
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Chapter11-ImageSequenceAnimation"
{
    Properties {
        _Color  ("Color  Tint",  Color)  =  (1,  1,  1,  1)
        _MainTex  ("Image  Sequence",  2D)  =  "white"  {} //_MainTex就是包含了所有关键帧图像的纹理
        _HorizontalAmount  ("Horizontal  Amount",  Float)  =  4
        _VerticalAmount  ("Vertical  Amount",  Float)  =  4 //_HorizontalAmount和_VerticalAmount分别代表了该图像在水平方向和竖直方向包含的关键帧图像的个数
        _Speed  ("Speed",  Range(1,  100))  =  30 //_Speed属性用于控制序列帧动画的播放速度
    }

    Subshader {
        Tags  {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}

        //序列帧图像通常包含了透明通道,因此可以被当成是一个半透明对象。
        Pass {
            Tags  {  "LightMode"="ForwardBase"  }
            ZWrite  Off
            Blend  SrcAlpha  OneMinusSrcAlpha  //使用Blend命令来开启并设置混合模式,同时关闭了深度写入

            CGPROGRAM
            #pragma vertex vert  
			#pragma fragment frag
            #include "UnityCG.cginc"

            fixed4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _HorizontalAmount;
            float _VerticalAmount;
            float _Speed;

            struct a2v {  
                float4 vertex : POSITION; 
                float2 texcoord : TEXCOORD0;
            };

            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert (a2v v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target {
                float time = floor(_Time.y * _Speed); //_Time.y是t,_Time.y和速度属性_Speed相乘来得到模拟的时间
                float row = floor(time / _HorizontalAmount); //time除以_HorizontalAmount的结果值的商来作为当前对应的行索引
                float column = time - row * _HorizontalAmount; //除法结果的余数则是列索引
               
                //使用行列索引值来构建真正的采样坐标
                //方案一:先缩放后偏移
                half2 uv = float2(i.uv.x /_HorizontalAmount, i.uv.y / _VerticalAmount); //把原纹理坐标i.uv按行数和列数进行等分,得到每个子图像的纹理坐标范围
                // 使用当前的行列数进行偏移,得到当前子图像的纹理坐标
                // 对竖直方向的坐标偏移使用减法,因为Unity纹理坐标(从下到上)和序列帧顺序(从上到下)相反
                uv.x += column / _HorizontalAmount;
                uv.y -= row / _VerticalAmount;
                //方案二:先偏移后缩放
                //half2 uv = i.uv + half2(column, -row); 
                //uv.x /=  _HorizontalAmount;
                //uv.y /= _VerticalAmount;
                
                fixed4 c = tex2D(_MainTex, uv);
                c.rgb *= _Color;
                return c;
            }
            ENDCG
        }

       
    }
    FallBack "Transparent/VertexLit"

}

在本书资源中,我们提供了这样一张图像(Assets/Textures/Chapter11/Boom.png)

https://github.com/candycat1992/Unity_Shaders_Book/blob/master/Assets/Textures/Chapter11/boom.png

《Unity Shader》11.2.1序列帧动画 爆炸

相关推荐
心前阳光20 小时前
Unity 模拟父子关系
android·unity·游戏引擎
在路上看风景1 天前
26. Mipmap
unity
咸鱼永不翻身1 天前
Unity视频资源压缩详解
unity·游戏引擎·音视频
在路上看风景1 天前
4.2 OverDraw
unity
在路上看风景1 天前
1.10 CDN缓存
unity
ellis19701 天前
Unity插件SafeArea Helper适配异形屏详解
unity
nnsix2 天前
Unity Physics.Raycast的 QueryTriggerInteraction枚举作用
unity·游戏引擎
地狱为王2 天前
Cesium for Unity叠加行政区划线
unity·gis·cesium
小贺儿开发2 天前
Unity3D 八大菜系连连看
游戏·unity·互动·传统文化
在路上看风景2 天前
25. 屏幕像素和纹理像素不匹配
unity