原文:Unreal Engine 4 Materials Tutorial
作者:Tommy Tran
譯者:Shuchang Liu
通過這篇教程,你將學會如何在材質編輯器里修改貼圖,創建材質實例,以及在游戲中修改更新材質實例。
一如現實世界,游戲世界也有各種各樣的物體,各自擁有獨特的外觀。在Unreal引擎里,材質決定了物體的外觀。物體的顏色?它的光澤度?是否透明?一切都定義在材質里。
在Unreal引擎中,材質被應用在基本所有可視元素里。你可以對網格、粒子、UI元素應用材質。
在本篇教程里,你將學會:
- 操作材質修改亮度和顏色
- 使用材質實例來快速生成變體
- 使用動態材質實例來在游戲收集道具過程中修改模型的顏色
在本篇教程里,你會接觸到材質和藍圖編輯器。如果你還不是很熟悉,請閱讀入門教程和藍圖教程教程。
注意:本篇教程只是Unreal Engine 4系列教程的其中一篇:
起步入門
下載示例項目並解壓。進入項目文件夾,雙擊BananaCollector.uproject打開項目。
注意:如果你看到了項目是由較早的引擎版本創建的提示,這很正常(因為引擎經常更新版本)。你可以選擇以拷貝副本的形式打開,也可以直接轉換項目版本打開。
我們可以看到有塊鋪滿香蕉的區域。按下Play,使用W,A,S和D鍵控制紅色方塊。你可以通過移動方塊方塊香蕉。
首先,我們需要修改香蕉材質來改變其亮度。Content Browser進入Materials文件夾雙擊M_Banana,打開材質編輯器。
為了調整香蕉的亮度,我們需要修改貼圖。
修改貼圖
貼圖本質就是一張圖片,而圖片是像素點的集合。一張彩色圖片,它的像素點顏色是由紅(R),綠(G)和藍(B)三個通道值所確定的。
下面是一張2x2像素的圖片,每個像素點的RGB值如文本所示。
注意:在Unreal引擎中,RGB各通道值的范圍為0.0~1.0。然而,在很多其他應用中,RGB各通道值為0~255。這僅僅是兩種不同的表示方式,並不代表Unreal引擎的顏色范圍更小。
我們可以通過對貼圖的每個像素值做數值操作從而修改貼圖。這種操作可以是簡單的增加每個像素點通道值。
下面的例子是將各通道值的范圍調整成0.4~1.0。這樣各通道的最小值不小於0.4,就使得圖片看起來更亮了。
我們可以如下圖一樣在材質編輯器完成上述操作:
接着,我們會使用Multiply(乘法)節點來調整貼圖的亮度。
Multiply節點
顧名思義,Multiply節點對兩個數值輸入做乘法操作。
使用乘法,我們可以在不影響色相和飽和度情況下,改變像素亮度。下面的例子里,通過對每個像素點通道值乘以0.5,將圖片的亮度減半。
通過給每個像素做上述操作,就可以改變整個貼圖的亮度。
雖然下面所說並非教程重點,但我們也可以通過使用Multiply節點連接一張遮罩貼圖。使用了遮罩貼圖,原貼圖的某些區域看起來就會更暗了。下面是使用瓷磚紋理來遮罩石頭紋理的例子:
其遮罩原理是像素點的灰度范圍在0(黑色)到1(白色)之間。
白色像素區域的原圖亮度最高,因為其像素點通道值乘以了1,灰色區域的亮度暗淡些,因為通道值乘以了小於1的數值,黑色區域完全無亮度,因為通道值乘以了0。
現在,讓我們試試Multiply節點吧。
調整貼圖亮度
首先我們需要去掉Texture Sample和Base Color引腳之間的連線。我們可以通過右鍵點擊引腳或者連線去掉連接。同樣的,按住Alt鍵,鼠標左鍵點擊連線也可去掉連接。
接着創建Multiply和Constant節點。你可以通過長按M鍵(Multiply節點)或者1鍵(Constant節點)並左鍵點擊空白區域,快捷創建對應節點。隨后如下圖一樣連線:
這樣貼圖的每個像素值都會與Constant節點值相乘。最后,將修改后的貼圖作為Base Color輸出。
現在,貼圖看起來應該是黑色的,因為乘數為0(Multiply節點默認值為0)。為了修改乘數,選中Constant節點,在Details面板將Value改為5。
點擊Apply並返回主編輯器。可以看到香蕉顏色變得更亮了。
我們還可以通過添加一些不同顏色的香蕉來豐富畫面效果。雖然我們可以新增不同顏色的材質,創建材質實例是一種更為簡便的方法。
關於材質實例
材質實例是材質的一種副本。對於原材質的任何修改都會在連帶影響材質實例。
材質實例的好處在於不用重新編譯而使得修改生效。你可能注意到了,每次我們修改了材質並點擊Apply按鈕,面板都會提示shader編譯信息。
通常來說這個過程只會持續數秒時間。然而,隨着材質變得復雜,編譯時間會急劇增加。
下面兩種場景很適合使用材質實例:
- 材質非常復雜,而且你希望可以快速進行修改
- 希望根據原材質創建材質變體,比如希望修改顏色,亮度甚至貼圖。
以下場景所有物體都使用了材質實例來修改顯示顏色,其實這些實例都共用了同一個材質。
在使用材質實例前,你需要為原材質創建參數。這樣材質實例才會顯示同樣的參數,使得我們可以調整材質的參數。
創建材質參數
回到主編輯器,並確保仍然處於編輯M_Banana材質的狀態。
首先,我們需要一個節點來修改貼圖的色相。HueShift節點就可以勝任。添加節點,並如下圖進行連線:
- 按住Alt鍵並左鍵點擊連線斷開Multiply節點與M_Banana節點的連接。
- 右鍵點擊 Blueprint面板,搜索HueShift節點並選中。
- 如上圖所示進行連線。
接着,我們需要創建Scalar Parameter節點。這個節點有一個可編輯的字段值。我們可以通過按住S鍵並左鍵點擊空白區域快速創建,然后連接HueShift節點的Hue Shift Percentage(S)引腳。
這里我們最好重新命名這個參數。選擇Scalar Parameter節點,並在Details面板將變量名改為HueShiftPercentage。
我們也可以將Constant節點轉換為Scalar Parameters節點。右鍵點擊剛才創建的Constant節點,選擇Convert to Parameter選項,然后將變量名改為Brightness。
現在材質參數就算設置好了。點擊Apply並關閉材質編輯器。
接着,我們要創建一個材質實例。
創建材質實例
將Content Browser切換到Materials文件夾。右鍵點擊M_Banana,並在彈出菜單中選擇Create Material Instance。將新資源重命名為MI_Banana_Green。
雙擊MI_Banana_Green打開材質實例編輯器。
編輯器由三個主要面板組成:
- Details:展示設置參數及其他通用參數。
- Instance Parents:展示當前實例的父類材質列表。在這個例子里,父類只有M_Banana。
- Viewport:展示當前材質實例的預覽球形網格。通過長按左鍵移動鼠標旋轉預覽網格,滑動滾輪縮放界面。
為了改成預覽香蕉網格,可以在Details面板的Previewing部分,左鍵點擊Preview Mesh下拉框,選擇SM_Banana。現在就可以看到預覽網格變成了香蕉。
接着,我們需要編輯參數將香蕉顏色改成綠色。為了編輯參數,要先勾選每個參數的勾選框。
將Brightness改為0.5,HueShiftPercentage改為0.2。你會看到如下圖的效果:
現在你已經創建好了材質實例,是時候應用在游戲的香蕉上了。關閉材質實例編輯器,回到主編輯器。
應用材質實例
我們可以單獨編輯放入場景的每個角色。意思是我們可以修改一個香蕉的材質而不影響其他香蕉。我們可以通過這點將某些香蕉改成綠色的。
選擇任意香蕉並在Details面板的組件列表中選中StaticMesh組件。
Details面板會顯示出StaticMesh組件的參數,將材質參數改成MI_Banana_Green。
重復如上操作,讓場景不同顏色的香蕉分布得更加隨機。看你能不能自己創建一個材質實例來制作一些紫色的香蕉吧!
動態變化材質
材質的作用也不僅限於美化畫面;我們也可以利用材質來做一些游戲設計。接着,你會學習如何利用材質,伴隨方塊收集了越來越多的香蕉,動態地將方塊顏色由白改成紅色。
在我們創建材質實例前,我們需要先設置好方塊的材質。
在Materials文件夾雙擊M_Cube打開材質編輯器。
首先需要創建顏色。你能看到Constant3Vector節點連接了Base Color引腳。這個節點非常適合用於設置顏色,因為它有RGB通道。
既然已經有了紅色,那還需要創建白色。我們通過按住數字鍵3,左鍵點擊空白處快捷創建Constant3Vector節點。
通過雙擊Constant3Vector節點打開Color picker。
通過滑動條或者在R,G,B通道輸入1.0將顏色設為白色,然后點擊OK按鈕。
為了平滑地將顏色從白色改為紅色,最簡便的方法就是使用線性插值。
什么是線性插值?
線性插值是一種獲得[A,B]范圍內某個數值的方法。比如,我們可以通過線性插值查找100和200之間的中間值。
通過控制Alpha值,線性插值的作用就顯現出來了。你可以將Alpha當成A到B點的百分比。Alpha為0時返回A,Alpha為1時返回B。
比如,你可以隨時間增加Alpha,來將一個物體從A點移動到B點。
在本篇教程中,你將通過收集香蕉數量來逐步增加透明度。
使用LinearInterpolate節點
首先,通過長按L鍵左鍵點擊空白處快捷添加LinearInterpolate節點。
接着,創建Scalar Parameter節點並將其命名為ColorAlpha。隨后如下圖進行連線:
小結:LinearInterpolate節點會輸出A值。因為Alpha值為0。Alpha值越接近1,輸出越接近B值。
材質現已制作好了。后續還有很多東西需要做,但我們可以看看現在的進度,點擊Apply並關閉材質編輯器。如果你點擊Play,應該可以看到方塊現在是白色而不是紅色的。
為了讓方塊改變顏色,你需要編輯ColorAlpha參數。然而還有一個問題,你不能在游戲運行中修改材質實例參數。解決方案是使用動態材質實例。
關於動態材質實例
不同於其他實例,你可以在游戲中通過藍圖或C++編輯動態材質實例。
你可以使用動態實例實現很多功能,比如一點點修改物體不透明度直至完全不可見。或者,你可以在物體沾濕時增加物體高光。
還有一個好處是使用動態材質實例,意味着你可以單獨修改每個物體。
下面例子是使用動態修改每個材質實例,實現了物體漸隱。
創建動態材質實例
你只能在游戲中通過藍圖或C++創建動態材質實例。
Content Browser窗口雙擊進入Blueprints文件夾,雙擊BP_Player打開藍圖編輯器。
首先要做的就是創建動態材質實例,並將其應用在方塊上。在Unreal生成角色的時機,也就是Event BeginPlay節點觸發時,做這件事比較合適。
確保在Event Graph上添加了Event BeginPlay節點。
現在,添加 Create Dynamic Material Instance (StaticMesh)節點。這個節點會同步創建並給方塊應用動態材質實例。
接着,你需要指定方塊應用哪個材質。點擊Source Material下拉框選擇M_Cube。
為了方便后續引用材質,最好用變量表示這個材質。最簡單的方法是在節點的Return Value引腳右鍵點擊,隨后點擊彈出菜單的Promote to Variable。
觀察My Blueprint頁簽,可以看到出現了新變量。按下F2鍵將其快捷重命名為CubeMaterial。
最后,連接Event BeginPlay與Create Dynamic Material Instance節點。
小結:一旦Unreal生成BP_Player,就會創建動態材質實例並將其應用到StaticMesh組件上,該實例會儲存成變量CubeMaterial。
下一步就該創建計數器用於統計香蕉收集數量了。
創建香蕉計數器
如果把面板往下拖,你能看到如下的節點連接。我們會利用這部分節點來更新香蕉計數器和材質。
On Component Begin Overlap節點會在方塊接觸其他角色時觸發執行。接着,Cast to BP_Banana節點會檢查觸碰角色是不是香蕉,如果是,則DestroyActor節點會將其銷毀並移出游戲。
現在我們要做的第一件事是創建變量存儲已搜集香蕉數量。隨后我們要在每次方塊觸碰香蕉時累加該變量。
創建Float變量並將其命名為BananaCounter。將變量拖拽至Event Graph並從彈出菜單中選擇Get。
為了讓計數器每次自增加一,添加IncrementFloat節點,然后連接BananaCounter節點。
接着,連接DestroyActor節點與IncrementFloat節點。
現在,玩家每收集一個香蕉,BananaCounter變量就會自增加一。
如果你直接使用BananaCounter作為alpha值使用,並不會得到預期結果。因為LinearInterpolation節點的alpha值范圍是[0,1]。你可以通過歸一化將計數轉化為[0,1]之間的值。
我們使用BananaCounter節點值除以一個預設值來進行歸一化。這個預設值代表着需要收集多少根香蕉才能讓方塊徹底變紅色。
添加float / float節點並將其左上角引腳與IncrementFloat節點相連。
將float / float節點的底部值設置為6。這意味着玩家需要收集6根香蕉讓方塊徹底變紅色。
這里還有個小問題。當玩家收集了超過6根香蕉,alpha值會超過1,為了修正這點,再使用Clamp (float)節點將輸出范圍限制在[0,1]。
現在,有了alpha值,是時候用它來更新材質了。
更新材質
將CubeMaterial變量拖拽至Event Graph,從彈出菜單中選中Get。
接着,拖拽CubeMaterial變量引腳到空白處,會彈出該變量類型的可用節點列表菜單。選中任意節點后,該節點都會自動連上變量節點。我們添加Set Scalar Parameter Value節點,該節點用於給參數設值。
現在,你需要指明更新的參數。將Parameter Name字段改為ColorAlpha。這個就是方塊材質所用的參數名。
連接Clamp (float)節點的返回值與Set Scalar Parameter Value node節點的Value引腳。
最后,連接IncrementFloat節點與Set Scalar Parameter Value node節點。
以下是藍圖執行的順序:
- On Component Begin Overlap (StaticMesh):當方塊與其他角色觸碰時觸發執行
- Cast to BP_Banana:檢查觸碰角色是否為香蕉
- DestroyActor:如果觸發到了香蕉,銷毀移除香蕉
4.IncrementFloat:BananaCounter變量自增加一
5.float / float:計數器除以特定數值進行歸一化
6.Clamp(float):限制上一步的輸出值不大於1
7.Set Scalar Parameter Value:將上一步的輸出值作為方塊材質的ColorAlpha參數值。
至此大功告成,一起來檢驗成果吧!點擊Compile並關閉藍圖編輯器。
點擊Play並開始收集香蕉。方塊一開始是白色的,隨着收集了越來越多的香蕉,方塊變得越來越紅。一旦收集了超過6根香蕉,它就會徹底變紅。
后續學習
你可以在這里下載完整項目。
我喜歡材質,因為它們威力強大,能做很多事情。你可以通過搭配不同材質創建更復雜的材質效果,比如縫隙中覆蓋着蘚苔的石頭。你也可以實現像教程動圖里所展現的炫酷的溶解效果。
如果你希望學習更多關於材質的內容,推薦你閱讀Unreal引擎文檔關於材質輸入部分內容。學習了解這些,有助於你創建一些更高級的材質。
我建議你多嘗試用不同的節點(還有很多其他節點)實驗各種效果。畢竟實踐出真知 :)
如果你還想繼續學習引擎其他內容,點擊下篇教程,將講解如何在游戲中使用文本,按鈕等UI元素。
