《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序列帧动画 爆炸

相关推荐
叶帆4 天前
【YFIOs】用C#开发硬件之设备上云
开发语言·unity·c#
久数君4 天前
AI三维建模工具“造形家”:地理场景三维化的高效解决方案
unity·glb·ai算法·ai三维建模工具·地图框选·造形家·城市建筑模型
会思考的猴子5 天前
Unity VFX 属性 Postion 和 TargetPostion
unity
hai3152475435 天前
九章编程法 · 猜数字游戏 (GW-BASIC 重构版) *
人工智能·microsoft·游戏引擎·游戏程序
心前阳光5 天前
Unity资源导入之自动化资源导入
unity·自动化·游戏引擎
心前阳光5 天前
Unity之2021.3.45f2c1发布安卓程序遇到的问题
android·unity·游戏引擎
纪纯5 天前
PicoVR Unity Integration SDK 3.4 常用交互API
unity·游戏引擎·vr·pico
龙智DevSecOps解决方案5 天前
3A 游戏优化技术栈:如何打通引擎级分析工具与 DevOps 持续集成管线?
unity·性能优化·游戏开发·技术美术·perforce·unrealengine
葛兰岱尔5 天前
从 SolidWorks 到 Three.js,从 Inventor 到 Unity——制造业CAD模型“几何-语义一体化“转换,不再是天方夜谭!
开发语言·javascript·unity
鼎艺创新科技5 天前
三维电子沙盘中OSGB倾斜摄影数据的加载与渲染
游戏引擎·cocos2d