序列幀動(dòng)畫制作

我想都或多或少聽過(guò)序列幀動(dòng)畫,屬于紋理動(dòng)畫的其中之一,原理跟電影播放一樣,代碼如下:

Shader "Unlit/AnimationTest" {
    Properties {
        _Color ("Color Tint", Color) = (1, 1, 1, 1)
        _MainTex ("Image Sequence", 2D) = "white" {}
        _HorizontalAmount ("Horizontal Amount", Float) = 4
        _VerticalAmount ("Vertical Amount", Float) = 4
        _Speed ("Speed", Range(1, 100)) = 30
    }
    SubShader {
        Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
        
        Pass {
            Tags { "LightMode"="ForwardBase" }
            
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            
            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 = mul(UNITY_MATRIX_MVP, v.vertex);  
                o.uv = TRANSFORM_TEX(v.texcoord, _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 = float2(i.uv.x /_HorizontalAmount, i.uv.y / _VerticalAmount);
//              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"
}

序列幀動(dòng)畫的制作主要在于需要每個(gè)時(shí)刻計(jì)算該時(shí)刻下應(yīng)播放的關(guān)鍵幀的位置,并對(duì)該關(guān)鍵幀進(jìn)行紋理采樣。
  在上述代碼中,_MainTex是包含了所有關(guān)鍵幀圖像的紋理,_HorizontalAmount和_VerticalAmount分別代表了該圖像在水平方向和數(shù)值方向包含的關(guān)鍵幀個(gè)數(shù),_Speed屬性用于控制序列幀動(dòng)畫的播放速度。
  由于序列幀圖像通常是透明紋理,需要設(shè)置Pass的相關(guān)狀態(tài),以渲染透明效果。
  fragment中的代碼則是真正計(jì)算每個(gè)時(shí)刻該渲染什么樣的紋理。
float time = floor(_Time.y * _Speed); 中,_Time.y是自場(chǎng)景加載后經(jīng)過(guò)的時(shí)間,將其和_Speed相乘得到模擬的時(shí)間,這其實(shí)是用于調(diào)整動(dòng)畫播放的快慢,并用CG的floor函數(shù)對(duì)結(jié)果值取整來(lái)得到整數(shù)時(shí)間time,接下來(lái)是計(jì)算行索引和列索引
  可以自己在網(wǎng)上找張序列幀圖片綁定到一個(gè)material中,用上述shader程序,就可以運(yùn)行調(diào)節(jié)看到具體效果了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 111. [動(dòng)畫系統(tǒng)]如何將其他類型的動(dòng)畫轉(zhuǎn)換成關(guān)鍵幀動(dòng)畫? 動(dòng)畫->點(diǎn)緩存->關(guān)鍵幀 112. [動(dòng)畫]Unit...
    胤醚貔貅閱讀 13,510評(píng)論 3 88
  • 書寫的很好,翻譯的也棒!感謝譯者,感謝感謝! iOS-Core-Animation-Advanced-Techni...
    錢噓噓閱讀 2,428評(píng)論 0 6
  • 也曾憶起你翩翩然之形影,卻看不清大觀園中流淚的雙眸。 也曾詢問(wèn)過(guò)你的人生,卻不能理解那變幻莫測(cè)的宿命。 也曾在夢(mèng)里...
    蘇知沐閱讀 373評(píng)論 0 1
  • 在聽完伯凡老師的直播后,我便開始嘗試列時(shí)間清單。 時(shí)間清單很好列,就是在每天晚上把自己一天所做...
    007劉利珍閱讀 1,016評(píng)論 0 1
  • 在初中的時(shí)候我就立志學(xué)習(xí)文科,幻想著有一天上通天文下通地理。然而高中分班的時(shí)候被班主任循循善誘后留在了理科班,于是...
    colayan閱讀 455評(píng)論 0 0

友情鏈接更多精彩內(nèi)容