<aside> <img src="/icons/robot_gray.svg" alt="/icons/robot_gray.svg" width="40px" /> 本章重點: 如何在Unity Shader中應用Time
</aside>
名稱 | 類型 | 描述 |
---|---|---|
_Time | float4 | t是自該場景加載開始所經過的時間,4個分量的值分別是(t/20, t, 2t, 3t) |
_SinTime | float4 | t是時間的正弦值,4個分量的值分別是(t/8, t/4, t/2, t) |
_CosTime | float4 | t是時間的余弦值,4個分量的值分別是(t/8, t/4, t/2, t) |
unity_DeltaTime | float4 | dt是時間增量,4個分量的值分別是(dt, 1/dt, smoothDt, 1/smoothDt) |
可以看得出,都是佔用了32位的值。這與顯卡的構造有關(SIMD),可以自行查詢相關的資料。
<aside> <img src="/icons/drafts_gray.svg" alt="/icons/drafts_gray.svg" width="40px" /> 書中所給的圖片的第一行是火焰已經快燒完的,在課外練習中有修正後的版本
</aside>
代碼可能不好理解,所以這裏一步一步地說明。
需要預設一些參數:
首先是如何對某一格進行取樣,只需要除以水平方向和垂直方向的數量便可,相當於將[0, 1]範圍映射到[0, 1/8]的範圍中
uv.x /= _HorizontalAmount;
uv.y /= _VerticalAmount;
然後是移動「取樣格」。首先先忽略_Speed
的影響。已知,1秒會移動一次。所以使用floor
向下取整限制只有在經過了1秒後才會移動,所以time
相當於是移動的總次數。row
指的是第x行,而column
指的是第x列。通過將time / 水平數量
,得到垂直方向總共移動多少次,再將總次數減去已移動的次數,就是水平方向的移動次數。最後將得到的結果與原uv相加便可。
float time = floor (_Time.y);
float row = floor (time / _HorizontalAmount);
float column = time - row * _HorizontalAmount;
half2 uv = i.uv + half2 (column, -row);
例如: 經過了30.5秒,通過向下取整,得到30秒,所以總共移動了30格。30/8 = 3.75,即row = 3,所以column = 6。也就是說,水平方向移動6次,垂直方向移動3次。可以得到
注意: 垂直方向是往下的,而因為Texture是Repeat,所以會從上方開始往下移動。
通過在Shader中將time設置為30,可以得到這樣的圖片
將速度因數應用,相當於提升「取樣格」的移動速度而已。
float time = floor (_Time.y * _Speed);
<aside> <img src="/icons/drafts_gray.svg" alt="/icons/drafts_gray.svg" width="40px" /> 關鍵在對紋理進行均勻的等分,得到格子,並在格子中取樣。這一步能理解的話,那麼其它就不是問題了。
</aside>