效果:


序列幀圖片網上隨便找的,質量不是很好,重點不是它,不要在意。
思路:
1.之前都是在一張面片上直接映射一張紋理,IN.uv的范圍是0~1
現在要映射一張紋理上的一小塊區域,就要用這塊區域的uv去采樣后映射到面片。
所以:x方向,IN.uv.x/列數,范圍變化到0~(1/列數)
同理:y方向,IN.uv.y/行數,范圍變化到0~(1/行數)
2.根據時間驅動,加上當前sprite的偏移量
uv.x = cellX + SpriteColumnIndex*1.0 / _Column;
uv.y = cellY + SpriteRowIndx*1.0 / _Row;
3.用變換后的uv去采樣圖片
half4 c = tex2D(_MainTex,uv);
代碼有注釋:
Shader "Custom/SpriteAnimation" { Properties { _MainTex("main tex" ,2D) = ""{} _Row("行",Int) = 1 _Column("列",Int) = 1 _Speed("speed",Range(0,10)) = 1 } SubShader { Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" } Pass { Blend One OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct v2f { float4 pos:POSITION; float2 uv:TEXCOORD0; }; sampler2D _MainTex; float4 _MainTex_ST; int _Row; int _Column; float _Speed; v2f vert(appdata_base v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP,v.vertex); o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); return o; } half4 frag(v2f IN) :COLOR { float2 uv = IN.uv; float cellX = uv.x / _Column; float cellY = uv.y / _Row; //Sprite總數 int count = _Row * _Column; //在0到count-1 范圍內循環 int SpriteIndex = fmod(_Time.w*_Speed,count); //當前Sprite所在行的下標 int SpriteRowIndx = (SpriteIndex / _Column); //當前Sprite所在列的下標 int SpriteColumnIndex = fmod(SpriteIndex,_Column); //因uv坐標左下角為(0,0),第一行為最底下一行,為了合乎我們常理,我們轉換到最上面一行為第一行,eg:0,1,2-->2,1,0 SpriteRowIndx = (_Row - 1) - fmod(SpriteRowIndx,_Row); //乘以1.0轉為浮點數,不然加號右邊,整數除以整數,還是整數(有誤) uv.x = cellX + SpriteColumnIndex*1.0 / _Column; uv.y = cellY + SpriteRowIndx*1.0 / _Row; half4 c = tex2D(_MainTex,uv); return c; } ENDCG } } FallBack "Diffuse" }
- 本文固定鏈接: http://www.shihuanjue.com/?p=297
- 轉載請注明: 喬 2016年01月16日 於 是幻覺 發表
