Unity Shader 紋理取樣UV動畫 幀動畫
阿新 • • 發佈:2019-01-31
在Shader紋理取樣的運用中,靈活的對UV進行操作可以達到很多種很棒的效果,今天就來介紹一種簡單的動畫效果幀動畫。
效果圖:
用到的示例圖:
關鍵點就是對紋理取樣中的縮放(Tiling)與偏移(Offset)的理解,如圖:
正常情況下的取樣效果:
幀動畫要求每次只顯示一小張圖,然後練習跳轉顯示後續的圖,所以每次UV的範圍就不能在預設的0-1的範圍。
如給定的這張圖,寬為2,高為3,u的範圍(Tiling的X屬性)為 1/寬, v的範圍(Tiling的Y屬性)為1/高,設定看效果:
能取樣到小圖了,接下來就是通過程式碼控制偏移量,使每次的取樣結果都是按照我們想要的順序取樣下去就ok了,至於是通過C#程式碼去動態修改偏移量還是Shader中去修改,都是一個目的就是隨時間推移改變偏移量Offset。我這裡採用C#來修改Offset值:
using System.Collections; using UnityEngine; public class TextureUVST : MonoBehaviour { public int width; public int height; public int fps; int _index = 0; int _totalCount; float _uInterval;//u方向上偏移的單位間隔 float _vInterval;//v方向上偏移的單位間隔 Material _mat; void Start () { _totalCount = width * height; _uInterval = 1f / width; _vInterval = 1f / height; _mat = GetComponent<MeshRenderer>().material; _mat.SetTextureScale("_MainTex", new Vector2(_uInterval, _vInterval));//固定的 所以設定一次就行了 StartCoroutine(Play()); } IEnumerator Play() { while (true) { yield return new WaitForSeconds(1f / fps);//等待設定的一幀時間 //使用 //_mat.SetTextureOffset("_MainTex", new Vector2(_index % width * _uInterval, 1 - _index / width * _vInterval - _vInterval));//362514 正常的左上開始, 左到右,上到下 _mat.SetTextureOffset("_MainTex", new Vector2(_index / height * _uInterval, _index % height * _vInterval));//123456 //_mat.SetTextureOffset("_MainTex", new Vector2(_index % width * _uInterval, _index / width * _vInterval));//142536 //_mat.SetTextureOffset("_MainTex", new Vector2(_index / height * _uInterval, 1 - _index % height * _vInterval - _vInterval));//321654 //累加 _index++; _index %= _totalCount; } } }
Shader簡單的紋理取樣程式碼:
// Upgrade NOTE: replaced tex2D unity_Lightmap with UNITY_SAMPLE_TEX2D Shader "Custom/UVFrame2" { Properties{ _MainTex("MainTex",2d) = ""{} } SubShader{ pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" sampler2D _MainTex; float4 _MainTex_ST; struct v2f { float4 pos : POSITION; float2 uv : TEXCOORD0; }; v2f vert(appdata_full v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); //o.uv = TRANSFORM_TEX(float4(_TilingX,_TilingY,_OffsetX,_OffsetY), _MainTex); return o; } fixed4 frag(v2f IN) :COLOR { fixed4 color = tex2D(_MainTex, IN.uv); return color; } ENDCG } } }