欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity Shader 序列帧动画

程序员文章站 2022-03-25 21:32:32
...

原理:计算每个时刻需要播放的关键帧在纹理中的位置,当播放速度达到一定值时,看起来就是一个连续的动画

Shader "anim"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_HorizontalAmount("Horizontal Amount",Float) = 4 //水平方向关键帧图像个数
		_VerticalAmount("Vertical Amount",float) = 4 //垂直方向关键帧图像个数
		_Speed("Speed",Range(1,100)) = 30

    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue" = "Transparent" "IgnoreProjector" = "True" }
        LOD 100

        Pass
        {
			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
			fixed _HorizontalAmount;
			fixed _VerticalAmount;
			fixed _Speed;

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

            fixed4 frag (v2f i) : SV_Target
            {
                float time = floor(_Time.y * _Speed);
				float row = floor(time / _HorizontalAmount);
				float column = time - row * _HorizontalAmount;

				half2 uv = i.uv + half2(column, -row);
				uv.x /= _HorizontalAmount;
				uv.y /= _VerticalAmount;

                fixed4 col = tex2D(_MainTex, uv);
				
                return col;
            }
            ENDCG
        }
    }
}

首先把_Time.y和速度属性_Speed相乘得到模拟的时间,然后用floor函数对结果取整得到对应的行索引,除法结果的余数就是列索引.