## **叁、處理火焰顏色吧【利用SubstDesigner制作可以動態調整的RampTexture】**
### 三點一、為火焰添加顏色吧
**H子**:那么老師,現在這樣做的話,只能得到一個白色的看起來像是燃燒的火球的東西。要怎么樣給他加上顏色呢。直接貼一張紋理是不行的吧。
**AOI**:當然是不可以的。這樣出來的效果非常糟糕。為火焰添加顏色的方法其實有好幾種。比如做幾套Step操作,創建多套Silder,用不同的值去控制火焰的區間大小。然后對這些區間乘上一個顏色值,最后進行混合。當然這種做法比較麻煩,也會增加無謂的節點,所以我們采取RampTexture的做法。
**H子**:所謂的Ramp Texture是什么東西呢。
**AOI**:RampTexture本質上就是一種1D的紋理索引表,建立一定的規則,使得可以從紋理上查找到想要的數據。
**H子**:麻煩說中文。
**AOI**:......
**H子**:?
**AOI**:好的,首先,RGB顏色,本質上就是由RGB三個通道構成的,而三個通道本質就是黑白的灰度數據對吧。
**H子**:對的。
**AOI**:那么再追尋本質,所謂的黑白灰度數據,也就是說,是0-1的浮點型(float)數據對吧。
**H子**:沒錯。
**AOI**:那么,再來看UV,所謂的UV,在3D軟件里面,分UV使用的那個區間,名叫01區間沒錯吧。
**H子**:嗯。
**AOI**:那么再來追尋一下本質,所謂的UV,所謂的01區間,也就是說,其實UV空間就是一個平面坐標系,范圍就是[0-1]對吧。換一種思路,UV值,其實是一個具有兩個通道,單獨一個通道就是一個0-1的浮點型數據。
**H子**:啊!我懂了。也就是說,我有一張紋理,那么其實我只要利用兩個0-1區間內的浮點型作為UV數據,就可以獲得紋理對應UV值的像素對吧。也就是說,我使用混合出來,未經過step處理的數據,就可以用來當作UV值傳遞進去,獲得Ramp Texture上對應位置的顏色了。
**AOI**:說的沒錯,終于理解了嘛。
**H子**:那么動手吧,首先分析需求就是,一張紋理,從左邊到右邊,就代表是0-1的UV區間,也就是傳入顏色從黑色到白色,代表著映射到紋理從左邊到右邊得像素。
也就是說,如果我打算用混合后的數據轉變成顏色,我只需要制作從左邊到右邊代表著原始數據黑色到白色,也就是說從火焰的外焰到內焰的顏色。
**AOI**:說的沒錯。這次我們依舊使用SubstanceDesigner進行這個紋理的制作,并且暴露出參數,使得紋理可以在Unity里面調整。
首先打開之前做的S_Fire的項目,并且創建一個新的Graph,命名為FireRamp

然后創建新的Output節點。
而這次,我們需要創建三層顏色的卡通風格的RampTexutre。
首先,創建一個Shape節點,并且把類型設置為Square


這樣就可以得到一個占據整個畫布的方塊了
**H子**:然后就是利用Transformation2D節點進行方塊位置的控制嗎。

奇怪了
我調整了Offset,但是為什么看到偏移,但是紋理沒有任何變化呢。
**AOI**:這是Tiling的設置問題了。因為默認的Tiling模式都是水平和垂直兩個方向

也就是說,不管你怎么偏移,他都會自動全方向的陣列,全屏的白色方塊在水平和垂直方向都陣列。自然看不到任何變化。
解決的方法也很簡單,首先點擊Tilling Mode旁邊設置模式的按鈕

在彈出的菜單中選擇
**Absolute**
這樣,就可以對陣列模式進行設置。因為我們需要橫向移動用以改變RampTexture,縱向并沒有相關的需求,所以只要設置成垂直方向陣列即可。

現在再來移動一下,看看是不是好了。
**H子**:果然能達成目的了,但是為什么我增加X Offset的時候,他向左移動啊。
**AOI**:這個只能說是他的坐標系設計問題了。解決方法也很簡單。

點解Rotation項目下的180按鈕,即可將圖像旋轉180。這個時候,再拖動就可以了。而Offset可以雙擊直接輸入數字,這樣就可以直接填寫超出默認-0.5到0.5范圍的數據,得到期望的偏移值了。
**H子**:啊,我懂了。因為是黑白兩色,所以接下來就是用Blend節點進行兩個顏色的混合就是了吧。而要混合三個顏色,只需要再把已經進行混合的兩個顏色,用同樣的方法與第三個顏色混合就可以了。

好了!我做到了!
**AOI**:嗯,做的不錯。這個時候,只要暴露出顏色和Offset的參數,就可以在Unity里面直接操作三段顏色參數的混合了。具體就不再贅述,直接做吧。
對了,offset暴露出來的值都是float2,可以手動設置成float型的數據,并且設置0-1的數據范圍限制。但是這個時候,因為原來是float2,而當前只有一個值。這樣的后果就是一個變量的數據,會被XY軸同時使用。

所以剛才在Transformation2D節點進行設置的垂直方向陣列的做法,也有保護圖像縱向的效果。
你也可以完全不陣列試試看效果。
**H子**:還是算了......
做完之后再保存并且導出sbsar格式,再導入Unity就可以創建不同的材質和紋理了吧。

啊,確實看到了。
### 三點二、繼續完善Shader以便使用RampTexture
**AOI**:素材已經準備好了,原理也已經明白了。那么接下來就該繼續完善Shader以便于使用RampTexture了。

首先創建一個Append節點,這個節點用于合并通道。
創建后,把用于計算Step的數據,同時連到Append節點的兩個入口。
RG在這個時候分別代表UV兩個通道。然后再創建一個Texture2D節點。
并把定義火焰顏色用的Ramp Texture拖到該節點上,再把Append連到Texutre2D的UV入口上,使得合并后的數據作為UV被紋理使用。

然后把Texture2D的RGB出口鏈接到Emission
**H子**:啊!有效果了!

不過為啥中間看起來怪怪的,中間不是應該白色的嗎。為啥變成外焰的顏色了
**AOI**,這是因為Unity里面默認的貼圖陣列模式的原因。

選擇紋理便可在Inspector面板看到材質的參數。

可以見到。默認Warp Mode是Repeat,也就是說當紋理超出01區間后,就會自動重復。
所以在火焰中心見到外焰的顏色,一來是因為中心的值其實已經大于1,二來是因為紋理重復模式的原因,使得超出1的數據又在回到了從0開始讀取。
**H子**:也就是解決方法有兩個,一方面是混合計算的值控制不要超出1,其次是把Wrap Mode改成Clamp了。

可以了!
在材質面板調整參數就可以改變區塊的比例。

這個真是太方便了!